AndroidKeyStore管理及实现-基于源码7.1.1.r13

本文详细解析了Android KeyStore系统的架构与实现原理,从Java层、Framework层到Native层逐层深入,涵盖证书导入、服务接口调用等关键流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、   Java层代码实现及调用

1.       Apps接口调用—证书导入apk

(1)       代码路径为:packages/apps/Settings/src/com/android/settings/CredentialStorage.java

(2)       功能为UNLOCK/ INSTALL/ RESET

通过调用android.security.keystore的私有对象mkeyStore 的importkey(),put(),unlock()实现对应的功能,mkeyStore通过调用getInstance()函数进行实例化,如下图所示:

(3)       importkey函数是存储私钥文件(密码保护),put函数是存储证书文件,通过uid判断是否为SELF或者sameUser(权限控制)调用importKey时,需要传入参数为name,value,uid和flag,uid值用于认证功能,flag的作用没有理解,有懂的大牛欢迎留言指点

2.       Framwork层Service接口调用

(1)       代码路径为frameworks/base/keystore/java/android/security/keyStore.java

(2)       获取对应的KeyStore实例,通过调用Binder机制,获取名称为“android.security.keystore”的服务,并实例化私有变量mBinder,KeyStore提供了函数包括get(),put(),insert(),delete(),list(),lock(),unlock(),generate(),importkey(),sign(),vertify():

(3)       KeyStore中的importKey函数通过mBinder的importKey实现,mBinder提供了KeyStore的所有函数实现-代理模式,其中mBinder的赋值是通过ServiceManger.getServcie(“xxxx”)做为参数,通过IKeystoreService强制转换而成的:

(4)       Binder服务对应的代码路径为frameworks/base/core/java/android/security/IKeystoreService.aidl

基于该aidl文件生成对应的IKeystoreService.java 和IKeystoreService.cpp对应java bindings和C++bindings,如下图所示:

基于aidl文件生成对应的stub文件和Bnxxx. Bpxxx文件,其中Bnxxx类集成binder类,实现IKeystoreService,且提供了转换接口实现asInterface(IBinder obj):


3.       Framwork层ServiceManager接口实现

(1)       代码路径为frameworks/base/core/java/android/os/ServiceManager.java

(2)       Binder中的具体功能实现,是通过ServiceManager的getService函数获取,通过读取HashMap表来索引对应的iBinder:


(3)       所有的service的获取最终是通过ServiceManager.getIServiceManger,返回的,ServiceManager也是binder服务,最终的接口实现为BinderInternal.getContextObject()

(4)       BinderInternal.getContextObject()实现路径为framework/base/core/java/com/android/internal/os/BinderInternal.java,对应的接口实现是通过JNI实现的:

(5)       JNI的代码实现代码路径为frameworks/base/core/jni/ android_util_Binder.cpp

(6)       ProcessState的实现代码为frameworks/native/libs/binder/ProcessState.cpp:

4.       JDK层接口调用--AndroidKeyStore

 

二、   内核层代码实现及调用 – keystore1keystore2均调用keystore0的实现

1.       KeyStoreService实现—输出keystore可执行程序

Mian代码路径为system/security/keystore/keystore_main.cpp,Keymaster2支持硬件管理,则对应的keymaster2_open函数直接打开设备的相关处理函数,通过调用hw_get_module_by_class函数获取HAL接口,并且keymasterx_open函数调用的为mod->methods->open(xxx)函数:


(1)       Keymaster的实现方式分为HARDWARE_MODULE(keymaster2),VERSION_1_0(keymster1)和VERSION_0_0:

Keymaste0,keymaster1和keymaster2差异性为设备open接口,其中keymaster0和keymaster需要通过SoftKeymasterDevice进行,如下图为keymaster0,如果仅支持软件管理,则返回,否则wrapper成hardware:

 

2.       Kernel-HAL层代码实现

(1)       代码路径system/security/softkeymaster/keymaster_openssl.cpp


(2)       代码路径为system/keymaster/soft_keymaster_device.cpp,实现了keymaster1和keymaster2的初始化,这两类的master是通过SoftKeymasterDevice进行对应的指针初始化,keymaster1和keymaster2没有对应的实现函数[.methos=nullptr]:

 

3.       KeyStoreClient实现

(1)       代码路径为system/security/keystore/ keystore_cli.cpp,获取系统的service-“android.security.keystore”

(2)       代码路径为system/security/keystore/keystore_cli_v2.cpp和keystore_client_impl.cpp,对应的是版本v2客户端:

 

4.       KeyStoreServer实现

(1)       代码路径为system/security/keystore/keystore_main.cpp:

5.       硬件扩展简述

 

三、   IPC机制分析-Binder机制

1.       参考文档: mediaservice的实现及源码解析:http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html

通用的binder机制解析:http://blog.youkuaiyun.com/coding_glacier/article/details/7520199


2.       ServiceManager的代码路径为:./frameworks/native/cmds/servicemanager/service_manager.c,

(1)       打开binder驱动,判断selinux的启用情况,循环监听driver中的消息,并调用svcmgr_handler,进行处理,main函数为:

(2)       其中binder_open的功能为通过mmap方法获取一块private的内存,并通过bs->fd进行访问,返回bs(该结构体含有句柄fd, 句柄指向的mmap内存块,内存块的大小),代码路径为frameworks/native/cmds/servicemanager/binder.c,如下图所示:

(3)       通过loop监听到请求,如果请求是发送给svcmgr,则继续查看对应的服务,例如添加服务,查询服务,获取服务:


(4)       此处关注addservice的操作,调用函数为do_add_service(bs,s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid), 其中参数s为服务的名称(bio_get_string16(msg, &len)),handle为服务的处理句柄(bio_get_ref(msg))—函数的具体实现位于frameworks/native/cmds/servicemanager/binder.c中,功能类似server解析请求的数据包,添加的服务以svcinfo的信息存储到链表中svclist(该链表采用前向插入)

(5)       通过查询获取到对应的handle,然后通过回调函数,封装成replay并调用binder_send_reply发送到请求方:

3.       serviceManger做为所有服务的servcer,而特定的service是通过调用ServiceManger.addService(“xxxxx”)的方式进行服务注册,封装parcel发送请求实现对应服务的注册,代码路径为:

(1)     KeyStore以binder服务的形式提供给前端,最终导出库为libkeystore_binder,服务注册代码如下所示,代码路径为system/security/keystore/keystore_main.cpp:

(2)       keystore的注册是通过IserviceManager的addService进行注册的,通过封装对应的handler,以parcel的数据格式注册服务请求的逻辑frameworks/native/libs/binder/IServiceManager.cpp:

(3)       将本地Service的实现函数转换成对应的句柄,封装成Binder,调用的对应函数为writeStrongBinder(),最终封装发送的handler为binder->remoteBinder(),类型为BpBinder,即实际注册时service->remoteBinder():

(4)       Keystore_main为一个执行程序,通过把binder->localBinder()句柄封装在Parcel中以iocal方式驱动到servicemanger,再调用android::IPCThreadState::self()->joinThreadPool(),代码路径为frameworks/native/libs/binder/IPCThreadState.cpp,该函数为循环监听函数,通过min和mout与binderdriver进行通信:

4.       Binder的IPCThreadStat与ProcessState源码分析:

(1)       通过调用android::IPCThreadState::self()->joinThreadPool(),与Binder驱动的交互即ioctl通信交互,IPCThreadState::Self(),创建单例IPCThreadState,并且该单例是线程独享共享区的,并且对象初始化了ProcessState::self():

(2)       joinThreadPool函数,默认isMain是true,进入BC_ENTER_LOOPER循环状态:

(3)       其中processPendingDerefs()函数功能为清理掉所有的weak和strong引用:getAndExecuteCommand()功能为执行下一条命令并等待来自BinderDriver的响应


(4)       最终调用executeCommand(),基于命令码的机制进行响应数据:

 

四、   依赖机制应用-keystore Binder机制

1.       keystore注册的handler是android::sp<android::KeyStoreService>,后续的请求也是请求该handle,并转换成IKeyStoreService指针进行对应函数的调用。

2.       Binder对应的服务端接口路径为system/security/keystore/key_store_service.h,该头文件继承BnKeystoreService和IBinder,其中具体的函数实现是通过mKeyStore调用相关函数实现,BnKeystoreService的实现代码路径为system/security/keystore/include/keystore/IKeystoreService.cpp:


3.       Binder对应的客户端接口路径为system/security/keystore/ IKeystoreService.cpp中的class BpKeystoreService,

4.       Binder的请求是封装的parcel,通过循环监听进行服务的响应(不错的客户端-服务器架构)

(1)       Demo代码树为

l   IService:IInterface                      --纯虚函数(服务侧提供的功能)

l   BnService:BnInterface<IService>             -- 虚函数onTransact实现

l   BpService:BpInterface<IService>            --实现对应的服务侧函数,封装请求,并实现OnTranscat函数

l   Service:BnService<IService>                 --实现IService中的所有纯虚函数

l   Service.main                                      --调用Service的初始话和注册函数

l   Client.main                                       --调用serviceManger的getService并转换成IService接口

(2)       Keystore对应的代码树为:

l   IKeystoreService:IInterface                     --代码路径为security/keystore/include/keystore/IKeystoreSerivce.h

l   BnKeystoreService:BnInterface<IKeystoreService>--代码路径为security/keystore/include/keystore/IKeystoreSerivce.h

l   BpSrevice:BpInterface<IKeystoreService> -- 代码路径为security/keystore/IKeystoreSerivce.cpp

l   KeyStoreService:BnKeystoreService<IKeystoreService>--代码路径为system/security/keystore/ key_store_service.h

l   Keystore_main                                               --代码路径为system/security/keystore/keystore_main.cpp

l   Keystore_cli_v2                                             --代码路径为system/security/keystore/keystore_client_impl.cpp


 未完待续。。。

<think>好的,用户问的是如何用Linux命令解压ffmpeg-7.1.1.tar.xz这个文件。首先,我需要确认文件的格式。tar.xz是经过tar打包后再用xz压缩的,所以需要分两步解压,或者使用能够同时处理这两种压缩的工具。 接下来,考虑用户可能对Linux命令不太熟悉,应该给出详细的步骤和解释。常见的解压方法有两种:一种是先用unxz解压成tar,再用tar解包;另一种是直接使用tar命令的-J选项来处理。第二种方法更简便,应该优先推荐。 然后,需要检查用户系统是否安装了xz工具。大部分现代Linux发行版可能已经预装了,但如果没有,可能需要用户安装xz-utils。这里需要提醒用户安装相关软件包,比如使用apt或者yum的命令。 另外,用户可能遇到权限问题,解压后的文件可能属于root,所以可能需要使用sudo,或者在解压后调整权限。不过一般来说,用户解压到自己的目录应该没问题。 还要考虑用户是否需要保留原始压缩文件,解压后是否删除原文件。tar命令默认解压后保留原文件,如果需要删除,可以添加--remove-files选项,但通常不建议,除非用户明确要求。 最后,可能需要告诉用户解压后的目录结构,比如进入解压后的文件夹进行配置或编译,但用户的问题只问到解压,所以这部分可能不需要,但可以简要提及,帮助用户下一步操作。 总结下来,步骤应该是:首先安装xz工具(如果需要),然后使用tar命令解压,最后确认解压结果。命令示例要清晰,解释每个参数的作用,比如-J表示处理xz压缩,-v显示进度,-f指定文件名。同时提醒注意事项,比如文件名是否正确,路径是否正确等。</think>在Linux系统中解压`.tar.xz`文件需要分两步处理,这里为您提供两种常用方法: 方法一:分步解压 1. 先用`unxz`解压.xz文件: ```bash unxz ffmpeg-7.1.1.tar.xz ``` 这会产生一个`.tar`文件 2. 再用`tar`解包: ```bash tar -xvf ffmpeg-7.1.1.tar ``` 方法二:单步解压(推荐) ```bash tar -xJvf ffmpeg-7.1.1.tar.xz ``` 参数说明: - `-x`:提取文件 - `-J`:指定使用xz压缩格式 - `-v`:显示解压过程(可选) - `-f`:指定文件名 注意事项: 1. 如果系统提示`unxz`或`tar`命令不存在,需要先安装xz工具: ```bash # Debian/Ubuntu sudo apt install xz-utils # CentOS/RHEL sudo yum install xz ``` 2. 解压后会生成名为`ffmpeg-7.1.1`的目录(实际名称以压缩包内容为准) 3. 解压后建议检查文件完整性: ```bash ls -l ffmpeg-7.1.1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值