[翻译]ICS 证书存储实现第2部分(ICS Credential Storage Implementation, Part 2)

前言:

这是一篇关于Android安全的翻译,这是原文地址。接上一篇翻译。这一篇主要讲述了密钥和证书的后台服务,IKeyChainService.aidl的实现:KeyChain.apk,以及密钥和证书的访问权限管理,授权数据库的维护。

我会一段一段地复制原文,然后在下面给出翻译,如有图片,我会重新保存再上传,以免出现“图片无法显示的情况”。


原文:

ICS Credential Storage Implementation, Part 2

December 01, 2011

译文:

ICS 证书存储实现第二部分
2011年12月1日

原文:

In the previous entry, we found how Android's keystore daemon manages keys and certificates, and how to connect to it using the provided keystore_cli utility. Now we will look at the intermediate layers between the OS daemon and the public KeyChain API introduced in ICS.

译文:

前一部分,我们知道了Android的keystore守护进程是如何管理密钥和证书的,并且使用系统提供的keystore_cli工具连接这个服务。现在我们将要看一下系统守护进程和ICS引入的 KeyChain API的中间层实现。

原文:

Browsing the android.security package, we find two AIDL files: IKeyChainService.aidl and IKeyChainAliasCallback.aidl. This is a hint that the actual key store functionality, like most Android OS services, is implemented as a remote service that the public API's bind to. IKeyChainAliasCallback is just the callback called when you select a key via KeyStore#choosePrivateKeyAlias(), so it's of little interest. IKeyChainService has the actual methods KeyChain uses to get a handle to a private key or a certificate, plus some internal API's used by the Settings and certificate installer applications. Naturally, the whole interface is marked as hidden, so SDK applications cannot directly bind to the service.

译文:

浏览 android.security 包,我们找到两个AIDL文件,IKeyChainService.aidlIKeyChainAliasCallback.aidl,这暗示着,实际的 key store 方法,像很多Android系统服务一样,是以公开的API绑定一个远程服务实现的。IKeyChainAliasCallback 仅仅是一个回调,在你通过KeyStore#choosePrivateKeyAlias()选中一个密钥时调用,所以对它不感兴趣。IKeyChainServiceKeyChain 实际使用的方法,用来处理一个私钥或者证书,外加几个内部的API,给设置和证书安装应用使用。当然,整个接口被标记成hidden,因此SDK应用不能直接绑定到这个服务。

原文:

The IKeyChainService interface has one implementation, the KeyChainService in the KeyChain.apk system package. We find the source in packages/apps/KeyChain, so let's explore the app's configuration. Looking at the manifest reveals that it consists of three components: the KeyChainService, a KeyChainActivity, and a broadcast receiver, you guessed it, KeyChainBroadcastReceiver. The package is com.android.keychain and its sharedUserId is set to 'android.uid.system', which, as we saw in the previous article, is necessary to be able to send management commands to the native keystore daemon. Let's first examine the service.

译文:

IKeyChainService 接口有一个实现KeyChainService, 在系统包的KeyChain.apk中。我们在packages/apps/KeyChain中找到了源码,让我们探索这个应用的配置。查看manifest信息,它是由三个组件构成:KeyChainServiceKeyChainActivity 和一个 broadcast receiver,你猜到了,是KeyChainBroadcastReceiver。包名是com.android.keychain,它的sharedUserId设置成了'android.uid.system',我们在前面的文章中看到了,这是向底层的keystore守护进程发送管理命令所必须的。让我们先查看一下这个service。

原文:

As can be expected, the KeyChainService is a wrapper for the android.security.KeyStore class that directly communicates with the native keystore daemon. It provides 4 sets of functionality:

译文:

正如所料,KeyChainServiceandroid.security.KeyStore 类的一个包装,它和底层的 keystore 守护进程直接通信,提供了4个方法集合:

原文:

  • key store management: methods for getting private keys and certificates
  • trust store management: methods for installing and deleting CA certificates in the user trust store
  • key and trust store initialization: a reset() method that deletes all key store entries, including the master key, thus returning the key store to a 'not initialized' state; it also removes all user-installed trusted certificates
  • methods for querying and adding entries to the key access grant database (more on this later)

译文:

  • 密钥存储管理:获取私钥和证书的方法
  • 受信任存储管理:在用户信受任存储中安装和删除CA证书的方法
  • 密钥和证书存储初始化:reset()方法删除所有密钥存储实体,包括master key,这让key store回到了'not initialized'状态,它还会删除所有用户安装的受信任证书
  • 查询和添加密钥授权数据库实体的方法(稍后详细介绍)

原文:

Since the KeyChain application is running as the system user, any process that binds to its remote interface would technically be able to perform all key and trust store operations. To prevent this, the KeyChainService imposes additional access control on its users. It employs two mechanisms to achieve this: controlling access based on the caller's UID and a key access grant database. Deleting a CA certificate and resetting the key and trust stores are only allowed to the system user (those operations are typically called via the Settings app's UI, which runs as system), and installing a trusted CA certificate is only allowed to the system user or the certificate installer application (com.android.certinstaller package). Controlling access to the key store is a little bit more interesting: KeyChainService maintains a grants database (in /data/data/com.android.keychain/databases/grants.db) that maps UID's to the key aliases they are allowed to use. Let's have a look inside:

译文:

由于KeyChain 应用以 system user(译注:具有系统权限)运行,从技术上来说,任何绑定到它远程接口的进程,能够执行所有的密钥和受信任操作。为了防止这种情况,KeyChainService给它的用户强加了额外的访问控制。它利用两个机制达到这一点: 基于调用者的UID和一个密钥访问授权数据库控制访问。只允许系统用户删除一个CA证书和重置密钥及受信任存储(这些操作的典型调用是通过'设置'应用的界面,以'system'身份运行),只允许系统用户或者证书安装应用('com.android.certinstaller 应用')安装一个受信任的CA证书。控制密钥存储的访问比较有意思:KeyChainService 维护一个授权数据库(在 /data/data/com.android.keychain/databases/grants.db),它把UID映射到了允许使用的密钥别名。让我们一探究竟:

# cd /data/data/com.android.keychain/databases
cd /data/data/com.android.keychain/databases
# ls
ls
grants.db
grants.db-journal
# sqlite3 grants.db
sqlite3 grants.db
sqlite> .schema
.schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE grants (  alias STRING NOT NULL,  uid INTEGER NOT NULL,  UNIQUE (al
ias,uid));
sqlite> select * from grants;
select * from grants;
test|10044
key1|10044

原文:

In this example, the application with UID 10044 (our test application) is granted access to the keys with the test and key1 aliases.

译文:

在这个例子中,UID是10044的应用(我们的测试应用)被授权访问别名为'test'和'key1'的私钥。

原文:

Each call to getPrivateKey() or getCertificate() is subject to a check against the grants database, and results in a exception if a grant for the required alias is not found. As stated before, KeyChainService has API's for adding and querying grants, and only the system user is allowed to call them. But who is responsible for actually granting and revoking access? Remember the private key selection dialog from the first article? When you call KeyChain#choosePrivateKeyAlias(), it will start the KeyChainActivity introduced above, which will check if the key store is unlocked, and if so, show they key selection dialog. Clicking the 'Allow' button will return to the KeyChainActivity, which will then call KeyChainService#setGrant() with the selected alias, adding it to the grants database. Thus, even if the activity requesting access to a private key has the needed permissions, the user has to unlock the key store and explicitly authorize access to each individual key.

译文:

每一次 getPrivateKey()getCertificate()调用,都要经受授权数据库的检查,如果没有找到所需别名的授权,将会产生一个异常。正如前面所说,KeyChainService有添加和查询授权的API,并且只允许system应用调用。那么谁在真正负责授权和撤消授权呢?还记得第一篇的private key selection dialog吗?当你调用KeyChain#choosePrivateKeyAlias()时,会启动前面介绍的 KeyChainActivity,它会检查密钥存储是否解锁,如果是,显示密钥选择对话框。点击 'Allow'按钮,会回到KeyChainActivity,这时它用已选的别名调用KeyChainService#setGrant(),把它添加到授权数据库。这样,即使请求访问一个私钥的activity拥有所需权限,用户不得不解锁key store 并且显式地给每个私钥授权。

原文:

Besides controlling private key storage, the KeyChainService also offers trust store management by using the newly added TrustedCertificateStore class (part of libcore). This class provides both the ability to add user-installed trusted CA certificates and remove (mark as not trusted) system (pre-installed) CA's. Since the implementation is fairly complex and rather interesting, it will be the topic of another post.

译文:

除了控制密钥存储,KeyChainService 还通过新添加的TrustedCertificateStore 类(libcore的一部分),提供了信任存储管理,这个类即提供了添加用户安装的受信任CA证书的能力,还提供了删除(被标记为不受信任的)系统(预先安装的)的CA证书的能力。由于这个实现相当地复杂并且非常有趣,所以将是另一篇文章的主题。

原文:

The last component of the KeyChain app is the KeyChainBroadcastReceiver. It listens for a android.intent.action.PACKAGE_REMOVED broadcast and simply forwards control to the KeyChainService. On receiving the PACKAGE_REMOVED action, the service does some grant database maintenance: it goes through all entries and deletes those referencing packages that are no longer available (i.e., uninstalled ones). With this we now have the (almost) complete picture (click to enlarge):

译文:

KeyChain 应用的最后一个组件是KeyChainBroadcastReceiver。 它监听 android.intent.action.PACKAGE_REMOVED 广播,简单地把控制转发到KeyChainService。当接收到 PACKAGE_REMOVED action,这个 service 做了一些授权数据库维护:它遍历所有的条目,删除那些不再可用的引用package(例如,被卸载的应用)。现在我们有个(几乎)完整的图像(点击放大):

keystore-diagram.png

原文:

ICS introduces a new service that grants access to both the system key store (managed by the keystore daemon) and trust store (manged by the TrustedCertificateStore class) that backs the KeyChain API exposed in the public SDK. That makes it possible to control access to keys based on both the calling process's UID and the key access grant database, thus allowing for fine-grained, user-driven control over what keys each application can access. We've discussed most of the components this framework consists of in this and the previous entry. What remains is to look into the new trust store implementation introduced in Android 4.0. That will be the focus of the next post of this series.

译文:

ICS 引入了一个新的 service, 它给系统密钥存储(由keystore 守护进程管理)和受信任存储(由 TrustedCertificateStore 类管理)授权,它是暴露在公开的SDK中的KeyChain API的后台。它使得能够基于调用者进程的UID和密钥授权数据库控制访问。我们在这篇和前一篇文章中已经讨论了很多组成这个框架的组件。剩下的是查看 Android 4.0引入的新的受信任存储。这将是下一篇
的重点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容