前言:
这是一篇关于Android安全的翻译,这是原文地址。接上一篇翻译。
我会一段一段地复制原文,然后在下面给出翻译,如有图片,我会重新保存再上传。
原文:
ICS Trust Store Implementation
December 02, 2011
译文:
ICS信任存储实现
2011年12月2日
原文:
In the previous two posts we looked at the internal implementation of the Android credential storage, and how it is linked to the new KeyChain
API introduced in ICS. As briefly mentioned in the second post, there is also a new TrustedCertificateStore
class that manages user installed CA certificates. In this entry we will examine how the new trust store is implemented and how it is integrated in the framework and system applications.
译文:
在前面的两篇文章中,我们调查了Android证书存储的内部实现,以及它是如何连接到ICS新引入的KeyChain
API上。在这两篇文章中也简单提到,还有一个新的TrustedCertificateStore
类,它管理用户安装的CA证书。在这篇文章中,我们要检查新的存储实现方式和它是如何集成在framework和系统应用中的。
原文:
Storing user credentials such as passwords and private keys securely is of course essential, but why should we care about the trust store? As the name implies, the trust store determines who we trust when connecting to Internet servers or validating signed messages. While credentials are usually used proactively only when we authenticate to a particular service, the trust store is used every time we connect to a secure server. For example, each time you check GMail, Android connects to Google's severs using SSL and validates their certificates based on the device's trust store. Most users are unaware of this, unless some error occurs. Since the trust store is used practically all the time, and usually in the background, one could argue that it's even more important then credential storage. Up till Android 4.0, the OS trust store was hard wired into the firmware, and users had no control over it whatsoever. Certificates bundled in the store were chosen solely by the device manufacturer or carrier. The only way to make changes was to root your device, re-package the trusted certificates file and replace the original one (instructions from cacert.org here). That is obviously not too practical, and a major obstacle to using Android in enterprise PKI's. In the wake of major CA's being compromised practically each month this year, tools that make changing the default trusted certificates in place have been developed, but using them still requires a rooted phone. Fortunately, ICS has made managing the trust store much more flexible, and gives the much needed control over who to trust to the user. Let's see what has changed.
译文:
安全地保存用户凭据,例如密码和私有证书,当然是非常必要的,但我们为何要关心信任存储呢?正如名字所示,当我们连接到互联网或校验签过名的消息时,信任存储决定了我们信任谁。然而通常证书在我们认证一个特定服务时主动使用,但信任存储在我们每一次连接安全服务时使用。例如,你每次登录GMail,Android 用SSL连接到Google的服务,基于设备的信任存储校验它们的证书。很多用户感觉不到这个,除非发生了一些错误。由于信任存储几乎一直被使用,并且经常是在后台,可能有人会说,它甚至比证书存储更重要。直到Android 4.0,系统的信任存储在固件中通过硬件实现,用户无论如何都不能控制它。捆绑在存储中的证书由设备生产商各自选择。唯一改变的方式是root你的设备,重新打包信任证书文件并且替换原来的(说明来自 cacert.org here)。对于在企业PKI下使用Android,这明显难以实践,并且是一个主要的障碍。随着今年主CA几乎每个月被破坏, 修改默认信任证书的tools已经在开发了,但仍然需要在root过的手机上使用。 幸运的是,ICS已经使得管理信任存储更加灵活,并且在信任对象上给用户提供了很多所需的控制。让我们看看有哪些变化。
原文:
Pre-ICS, the trust store was a single file: /system/etc/security/cacerts.bks
, a Bouncy Castle (one of the JCE cryptographic providers used in Android) native keystore file. It contains all the CA certificates Android trusts and is used both by system apps such as the email client and browser, and applications developed using the SDK. Since it resides on the read-only system partition, it cannot be changed even by system-level applications. The newly introduced in ICS TrustedCertificateStore
class still reads system trusted certificates from /system/etc/security
, but adds two new, mutable locations to store CA certificates in /data/misc/keychain
: the cacerts-added
and cacerts-removed
directories. Let's see what's inside:
译文:
在ICS之前,信任存储是一个单独的文件, /system/etc/security/cacerts.bks
, 一个 Bouncy Castle(Android 使用的一个加密提供商)本地keystore 文件,它包括所有Android信任的CA证书,被系统应用例如邮件客户端和浏览器,以及用SDK开发的应用使用。由于它存在于只读的系统分区,所以就算是系统级别的应用,也不能修改它。ICS新引入的 TrustedCertificateStore
仍然从/system/etc/security
读系统信任证书,但是在/data/misc/keychain
下增加了两个新的,可变的CA证书存储位置:cacerts-added
和 cacerts-removed
目录,让我们看看里面有什么:
ls -l /data/misc/keychain
drwxr-xr-x system system 2011-11-30 12:56 cacerts-added
drwxr-xr-x system system 2011-12-02 15:21 cacerts-removed
# ls -l /data/misc/keychain/cacerts-added
ls -l /data/misc/keychain/cacerts-added
-rw-r--r-- system system 653 2011-11-29 18:34 30ef493b.0
-rw-r--r-- system system 815 2011-11-30 12:56 9a8df086.0
# ls -l /data/misc/keychain/cacerts-removed
ls -l /data/misc/keychain/cacerts-removed
-rw-r--r-- system system 1060 2011-12-02 15:21 00673b5b.0
原文:
Each file contains one CA certificate. The file names may look familiar: they are hashes of the CA subject names, as used in mod_ssl and other cryptographic software implemented using OpenSSL. This makes it easy to quickly find certificates without scanning the entire store. Also note the permissions of the directories: 0775 system system
guarantees that only the system
user is able to add or remove certificates, but anyone can read them. As can be expected, adding trusted CA certificates is implemented by storing the certificate in cacerts-added
under the appropriate file name. The two files above, 30ef493b.0
and 9a8df086.0
, correspond to the certificates displayed in the 'User' tab of the Trusted credential system application (Settings->Security->Trusted credentials). But how are OS-trusted certificates disabled? Since pre-installed CA certificates are still stored in /system/etc/security
(read-only), a CA is marked as not trusted by placing a copy of its certificate in cacerts-removed
. Re-enabling is performed by simply removing the file. In this particular case, 00673b5b.0
is the thawte Primary Root CA, shown as disabled in the 'System' tab:
译文:
每一个文件包含一个CA证书,文件的名称看起来相似,它们是CA主题名称的哈希,用在mod_ssl 和其他用 OpenSSL实现的加密软件上.这使得不用扫描整个存储就能很快找到证书.再看这些目录的权限: 0775 system system
确保只有系统用户才能添加或删除证书,但任何人可以读它们,正如所料,添加受信任CA证书是通过在cacerts-added
中以适当名称存储文件实现的.上面的两个文件 30ef493b.0
和 9a8df086.0
, 对应受信任证书 (设置->安全->受信任证书)系统应用的用户Tab中展示的证书。但是操作系统信任证书如何被禁止呢?由于预安装的CA证书仍然存储在 /system/etc/security
(只读),一个被标识为不信任的证书,通过在cacerts-removed
目录存放一份它的备份。简单删除这个文件就能重新启用。在这个特定的例子中,00673b5b.0
是主要的根CA, 在'System' tab显示和禁用。
原文:
TrustedCertificateStore is not available in the SDK, but it has a wrapper accessible via the standard JCE KeyStore API, TrustedCertificateKeyStoreSpi, that applications can use. Here's how we can use it to get the current list of trusted certificates::
译文:
TrustedCertificateStore 在SDK中是不可用的,但它有一个通过标准JCE KeyStore API 可访问的封装。TrustedCertificateKeyStoreSpi,应用程序可以使用,下面是我们如何使用它得到当前信任证书的列表:
KeyStore ks = KeyStore.getInstance("AndroidCAStore");
ks.load(null, null);
Enumeration aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
X09Certificate cert = (X509Certificate)
ks.getCertificate(alias);
Log.d(TAG, "Subject DN: " +
cert.getSubjectDN().getName());
Log.d(TAG, "Issuer DN: " +
cert.getIssuerDN().getName());
}
原文:
If you examine the output of this code, you would notice that certificate aliases start with either the user:
(for user installed certificates) or system:
(for pre-installed ones) prefix, followed by the subject's hash value. This lets us easily access the OS's trusted certificates, but a real word application would be more interested in whether it should trust a particular server certificate, not what the current trust anchors are. ICS makes this very easy by integrating the TrustedCertificateKeyStoreSpi
with Android's JSSE (secure sockets) implementation. The default TrustManagerFactory
uses it to get a list of trust anchors, thus automatically validating server certificates against the system's currently trusted certificates. Higher-level code that uses HttpsURLConnection
or HttpClient
(both built on top of JSSE) should thus just work without needing to worry about creating and initializing a custom SSLSocketFactory
. Here's how we can use the TrustManager
to validate a certificate issued by a private CA (the CA certificate is already installed in the user trust store).
译文:
如果你检查代码的输出,你会发现证书别名要么用user:
(对应用户安装的证书)开头,要么用system:
(对应预先安装的证书)为前缀,后面是主题的哈希值。这让我们容易访问系统信任的证书,但一个真正的应用应该对是否信任一个特定的服务证书更感兴趣,而不是当前信任的锚点,ICS通过集成 TrustedCertificateKeyStoreSpi
和 Android 的 JSSE(安全套接字)实现,让它变得很容易。默认的TrustManagerFactory
用它得到一个信任锚点的列表,从而参照系统当前信任的证书自动验证服务证书。上层的代码仅仅使用HttpsURLConnection
或HttpClient
(两个都是JSSE顶部结构)进行工作,不需要担心创建和初始化自定义的SSLSocketFactory
。下面是我们如何使用TrustManager
验证一个私有CA发行的证书(CA证书已经安装在用户信任存储中了)。
X509Certificate[] chain = KeyChain.getCertificateChain(ctx,
"keystore-test-ee");
Log.d(TAG, "chain length: " + chain.length);
for (X509Certificate x : chain) {
Log.d(TAG, "Subject DN: "
+ x.getSubjectDN().getName());
Log.d(TAG, "Issuer DN: "
+ x.getIssuerDN().getName());
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) null);
TrustManager[] tms = tmf.getTrustManagers();
X509TrustManager xtm = (X509TrustManager) tms[0];
Log.d(TAG, "checking chain with " + xtm);
xtm.checkClientTrusted(chain, "RSA");
Log.d(TAG, "chain is valid");
原文:
Works pretty well, but there is one major problem with this code: it does not check revocation. Android's default TrustManager explicitly turns off revocation when validating the certificate chain. So even if the certificate had a valid CDP (CRL distribution point) extension, pointing to a valid CRL, and the certificate was actually revoked, it would still validate fine in Android. What's missing here is the ability to dynamically fetch, cache and update revocation information as needed, based on information available in certificate extensions. Hopefully future version of Android will add this functionality to make Android's PKI support complete.
译文:
工作得很好,但这段代码有一个主要的问题,它不能检查吊销,Android默认的TrustManager 在校验证书链的时候,显式地关闭了吊销,因此即使证书有一个有效的CDP(证书吊销列表分发点) 扩展,指向一个有效的CRL(译注:证书吊销列表),并且证书已经真正被吊销,它在安卓中仍然验证通过。这里丢失了需要基于证书扩展中的可用信息自动获取,缓存和更新吊销信息的能力,希望未来的安卓版本能添加这个功能,使得安卓的PKI支持完整。
原文:
Of course, system applications such as the browser, email and VPN clients are also taking advantage of the new trust store, so connecting to a corporate Exchange server or a secure Web application should be as easy as installing the appropriate certificates. We'll see how well that works out in practice once I get a real ICS device (shouldn't be too long now...).
译文:
当然,系统应用例如浏览器,邮件,VPN客户端也能从新的信任存储中受益。因此链接到一个公司的Exchange 服务或者一个安全的Web应用,就和安装合适的证书一样容易。一旦我有一个真正的ICS设备,我们将看到在实践中是如何解决的(不会等很久的)。
原文:
That concludes our discussion of the new credential and trust stores introduced in Android 4.0. To sum things up: users can now freely install and remove private keys and trusted certificates, as well as disable pre-installed CA certificates via the Settings app. Third-party applications can also do this via the new KeyChain API, if the user grants the app the necessary permissions. The key and trust stores are fully integrated into the OS, so using standard secure communication and cryptographic Java API's should just work, without the need for applications-specific key stores. A key element required for full PKI support -- revocation checking, is still missing, but the key and trust store functionality added in ICS is a huge step in making Android more secure, flexible and enterprise-friendly.
译文:
这就是我们关于Android4.0上证书和信任存储的讨论,总而言之,用户现在可以自由地安装和删除私钥和信任证书,同样通过设置应用可以禁用预装的CA证书。如果用户授于必要的权限,三方应用也可以通过新的KeyChain API
实现这些。私钥和信任存储完全集成进了操作系统,因此使用标准的安全通信和加密的Java API就能工作,不需要应用指定私钥存储。对完整的PKI支持所需要的一个关键元素:吊销检查,仍在缺失,但私钥和信任存储功能添加到ICS是一个很大的进步,使Android更加安全,灵活并且企业友好了。
结语:
ICS信任证书系列的翻译,到这里就结束了,翻译完发现,这些内容在应用开发中,并没有多大用处。但通过对这些文章的阅读,可以增加对证书管理的理解,也能增加对网络通信安全的了解。