如何将 OpenSSL 指向 Android 设备上的根证书?

Posted

技术标签:

【中文标题】如何将 OpenSSL 指向 Android 设备上的根证书?【英文标题】:How to point OpenSSL to the root certificates on an Android device? 【发布时间】:2013-02-28 19:30:51 【问题描述】:

我已经设法交叉编译 OpenSSL for ARMv6 以与 the android NDK 一起使用,并让它在我的应用程序中运行。但是,当尝试与知名主机(例如https://google.com)建立 HTTPS 连接时,我总是收到错误消息“SSL 证书无效。”

但是,我可以在我设备的任何浏览器(常用浏览器、Chrome、Firefox 等)中显示安全页面。因此我只能假设 OpenSSL 没有找到存储在设备上的根证书。

然后我的问题分解为两个非常相关的子问题:

Android 将根证书存储在设备的什么位置? 如何将 OpenSSL 指向它们?

【问题讨论】:

【参考方案1】:

Android 将根证书存储在设备的什么位置?

它四处移动。随着冰淇淋三明治 (ICS) 的出现,使用了三个商店。这三个商店分别是/data/misc/keychain(Android提供)、/data/misc/keychain/cacerts-added(用户添加的CA)和/data/misc/keychain/cacerts-removed(用户删除或更新的CA)。

在 ICS 之前,他们使用位于 /system/etc/security/cacerts.bks 的 BouncyCastle 商店。这是一个静态存储,无法修改。如果需要更改,则需要更新固件或映像。

有关商店的说明,请参阅ICS Trust Store Implementation。这是 Nikolay Elenkov 的博客,他在讨论系统方面做得很好,而不仅仅是商店所在的位置。


如何将 OpenSSL 指向它们?

您无法真正做到这一点,因为 OpenSSL 期望和 Android 呈现的是两种不同的呈现/存储格式。 OpenSSL 期望将一组 PEM 格式的信任锚连接在一起。但 Android 信任库不是这种格式。

通常发生的是您下载cacert.pem。然后,通过将cacert.pem 指定为CAfile 参数,调用SSL_CTX_load_verify_locations 来加载它们。

即使您从受信任的来源(如 Mozilla 或 cURL)下载 cacert.pem,您仍应仔细检查并确保您对信任锚的集合感到满意。包中有 155 个潜在的信任锚:

$ cat cacert.pem | grep BEGIN | wc -l
     155

但就像我在评论中所说的那样,它隐含地使用了浏览器安全模型,在许多情况下它并不是一个特别好的做事方式。


在尝试与知名主机(例如https://google.com)建立 HTTPS 连接时,我总是收到错误消息“SSL 证书无效。”

要回答这个问题,只需使用Google Internet Authority 或GeoTrust Global CA 和SSL_CTX_load_verify_locations。最好使用 Google Internet Authority,因为它会限制网络投射。

谷歌互联网管理局

-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIDAjp2MA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMBcGA1UdIAQQ
MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQUFAAOCAQEAJ4zP6cc7vsBv6JaE
+5xcXZDkd9uLMmCbZdiFJrW6nx7eZE4fxsggWwmfq6ngCTRFomUlNz1/Wm8gzPn6
8R2PEAwCOsTJAXaWvpv5Fdg50cUDR3a4iowx1mDV5I/b+jzG1Zgo+ByPF5E0y8tS
etH7OiDk4Yax2BgPvtaHZI3FCiVCUe+yOLjgHdDh/Ob0r0a678C/xbQF9ZR1DP6i
vgK66oZb+TWzZvXFjYWhGiN3GhkXVBNgnwvhtJwoKvmuAjRtJZOcgqgXe/GFsNMP
WOH7sf6coaPo/ck/9Ndx3L2MpBngISMjVROPpBYCCX65r+7bU2S9cS+5Oc4wt7S8
VOBHBw==
-----END CERTIFICATE-----

GeoTrust Global CA

-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----

在理想情况下,您运行私有 PKI,并且您只信任 PKI 的根来认证站点和服务。您不授予信任公共 CA 来证明任何内容,因为它们不对依赖方作出任何保证。从本质上讲,公共 CA 会告诉您他们的warez 并不好,即使是出于将它们出售给网站的目的。

在次优世界中,您只使用认证站点的公共 CA。这意味着您使用 Google Internet Authority 或 GeoTrust Global CA 来认证 Google 资产;而不是,比如Diginotar。

还有其他不太明显的问题。 Google Internet Authority 是一个由 GeoTrust 认证的无约束从属 CA。 Google 可以为任何网站颁发证书,而不仅仅是 Google 资产。通常,这会被 RA 捕获,它实际上是一个独立的审计员,在签发之前验证对 CA 的签名请求。但在此模型中,提出请求的组织 (Google) 与验证请求的组织 (Google) 和颁发证书的组织 (Google) 相同。浏览器、CA 和 PKI 是我知道的唯一实例,独立审计员作为检查和平衡被完全删除because it was too inconvenient。

如果你认为下属不会做这种事,那你就大错特错了。 CNICC was just removed from a few browser trust stores,因为它的一个不受约束的下属被发现为未经授权的站点和服务颁发证书。

浏览器安全模型真正出问题的地方在于错误的 CA 能够认证站点。它包括对用户的成功网络钓鱼尝试。也就是说,浏览器很乐意允许连接被拦截,因为用户被钓鱼了。

如果您认为即将发布的Public Key Pinning with Overrides 会有所帮助,那么您就大错特错了。尽管他们几乎没有提到覆盖,但攻击者可以破坏已知的良好 pinset。更糟糕的是,报告功能会因带有不得报告的损坏的 pinset 而被禁用,因此浏览器是隐瞒的同谋。

关于该主题的阅读更多。首先,试试 Peter Gutmann 的 Engineering Security 和 Audun Jøsang 的 Trust Extortion on the Internet。

【讨论】:

【参考方案2】: android 根证书存放在哪里:

根据将证书添加到不同设备上的本地密钥库的大量问题,他们从一个版本到另一个版本,从一个设备到另一个设备。其中大多数要求设备被植根,后来 cmets 谈到解决方案会中断,因为他们在特定设备上移动或更改了格式。

如何将 openssl 指向它们:

我不确定现在是否有“好”的方法可以做到这一点。我能找到的最佳解决方法是this answer,然后将这些证书放入您自己的 openssl 理解的应用程序特定存储中。

一个不完美的解决方案,但你也许可以使用。

【讨论】:

【参考方案3】:

android在哪里存储根证书:

系统证书:这些存储在System/etc/security/cacerts.bks

第三方证书:这些证书存储在data/misc/keystore

如何将 openssl 指向他们:

android 操作系统与您的 openssl 库一起处理此问题。您不必手动指向它。

根据你提供的信息,我写在下面。

考虑到您的应用程序是 *** 或基于云的应用程序。

问题可能是由于您在设备中安装了无效的 SSL 根 CA 来检查 SSL 流量。

希望对你有帮助

【讨论】:

以上是关于如何将 OpenSSL 指向 Android 设备上的根证书?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ANDROID 应用程序中使用 openSSL 库

多个设备令牌目标指向 AWS SNS 中的单个 Android 设备

Android OpenGL表面崩溃在设备方向改变问题,怎么解决

QQ浏览器弹出“电脑管家云安全中心提醒您,该网站可能存在OpenSSL“心血”漏洞!”如何关掉

创建为您提供位置的按钮(Android Studio)

Ubuntu+NDK编译openssl(为了Android上使用libcurl且支持HTTPS协议)