当前位置: 首页 > news >正文

android keystore源码分析

架构

Android Keystore API 和底层 Keymaster HAL 提供了一套基本的但足以满足需求的加密基元,以便使用访问受控且由硬件支持的密钥实现相关协议。
Keymaster HAL 是由原始设备制造商 (OEM) 提供的动态加载库,密钥库服务使用它来提供由硬件支持的加密服务。为了确保安全性,HAL 实现不会在用户空间乃至内核空间中执行任何敏感操作。敏感操作会被分配给通过某个内核接口连接的安全处理器。 最终的架构如下所示:
访问 Keymaster

源码分析

源码分析基于Android 9.0

####AndroidKeyStore服务提供者

img

应用层调用时provider必须指明为"AndroidKeyStore",否则默使用的是BC库。

Android KeyStore 是Java 安全框架的一个提供者的实现,类名为AndroidKeyStoreProvider.java。

此类中定义了一些引擎类的实现:

  • AndroidKeyStoreSpi 存储服务
  • AndroidKeyStoreKeyPairGeneratorSpi$EC ECC密钥对生成
  • AndroidKeyStoreKeyPairGeneratorSpi$RSA RSA密钥对生成

等等,这部分的代码在

/frameworks/base/keystore/java/android/security/keystore/

这些引擎类的实现内部有一个android.security.KeyStore对象。此对象是一个binder代理。通过binder通信转到系统服务的KeyStoreSerivce。

KeyStoreService服务

服务代码在/system/security/keystore/key_store_service.cpp

KeyStoreService 内部持有一个KeyStore对象,

代码在/system/security/keystore/KeyStore.cpp

KeyStore对象内部持有一个device,此device是KeymasterDevices,此对象是三个Keymaster的数组,分别对应软实现、TEE实现和SE实现。如果是TEE实现的话,keymaster hal 应该就是CA程序。

当系统启动时会加载keymaster hal的实现,并把他注册到硬件的servicemanager 中。

keymaster hal

keymaster hal的注册,这里是安卓模拟器goldfish中的服务注册示例。

Cross Reference: /device/generic/goldfish/keymaster/strongbox/service.cpp


int main() {::android::hardware::configureRpcThreadpool(1, true /* willJoinThreadpool */);using android::hardware::keymaster::V4_0::SecurityLevel;using ::keymaster::V4_0::ng::CreateKeymasterDevice;/** Create two software keymaster devices claiming different security levels for testing* purposes. They do not have the certificates of real TEE or Strongbox keymaster devices.*/auto keymaster = CreateKeymasterDevice(SecurityLevel::TRUSTED_ENVIRONMENT);auto status = keymaster->registerAsService("default");if (status != android::OK) {LOG(FATAL) << "Could not register default service for Keymaster 4.0 (" << status << ")";}auto strongbox = CreateKeymasterDevice(SecurityLevel::STRONGBOX);status = strongbox->registerAsService("strongbox");if (status != android::OK) {LOG(FATAL) << "Could not register strongbox service for Keymaster 4.0 (" << status << ")";}android::hardware::joinRpcThreadpool();return -1;  // Should never get here.
}

keymaster枚举

Cross Reference: /system/security/keystore/keystore_main.cpp

KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {KeymasterDevices result;serviceManager->listByInterface(Wrapper::WrappedIKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {})
}

通过枚举获取keymaster的实现。构造keystore对象。

keymaster hal实现最终通过调用安全环境实现密钥生成、加密解密、签名验签。

keymaster 实现的接口定义如下。厂商只要按照规范要求实现此接口即可。

Cross Reference: /hardware/interfaces/keymaster/3.0/IKeymasterDevice.hal

Cross Reference: /hardware/interfaces/keymaster/4.0/IKeymasterDevice.hal

Android Keystore 机制总结

Android Keystore 提供安全的密钥管理和加密操作,其核心机制涉及多进程协作和跨空间调用。以下是关键组件及其交互流程:


重要类与组件
类/组件所在进程运行空间描述
android.security.KeyStore应用进程(如App进程)用户空间应用层API,提供密钥生成、存储等接口。开发者通过此类访问Keystore功能。
KeyStoreServicekeystore进程用户空间系统服务,处理应用请求,管理密钥生命周期,通过Binder与客户端通信。
KeymasterHAL (HIDL接口)厂商HAL进程(如vendor.some.process用户空间硬件抽象层接口,由厂商实现,执行加密操作(如密钥生成、签名)。
内核驱动(如/dev/keymaster内核内核空间与硬件安全模块(HSM/TEE/StrongBox)通信,处理安全环境内的敏感操作。

调用流程与通信机制
  1. 应用层调用
    • 进程: 应用进程 → keystore
    • 机制: Binder IPC
      • 应用通过 android.security.KeyStore 发起请求(如生成密钥)。
      • 调用通过 Binder 传递至 KeyStoreService(运行在 keystore)。
  2. 系统服务处理
    • 进程: keystore → 厂商HAL进程
    • 机制: HIDL/AIDL IPC
      • KeyStoreService 将请求转换为 Keymaster 操作(如调用 generateKey)。
      • 通过 HIDL 接口(如 IKeymasterDevice)与厂商的 KeymasterHAL 实现通信。
  3. 硬件抽象层执行
    • 进程: 厂商HAL进程 → 内核
    • 机制: 系统调用(ioctl)
      • KeymasterHAL 通过 ioctl 调用内核驱动(如 /dev/keymaster)。
      • 驱动将操作转发至安全环境(如 TEE 或 StrongBox)。
  4. 安全环境操作
    • 空间: 内核 → TEE/HSM
    • 机制: SMC指令或安全监控调用
      • 内核驱动通过安全机制(如 ARM TrustZone 的 SMC)触发安全环境内的操作。
      • 密钥在安全环境内生成/使用,不会暴露到非安全内存。

关键点总结
  • 用户空间与内核空间协作:敏感操作(如密钥生成)最终由安全环境(TEE/HSM)处理,确保密钥不泄露至普通内存。
  • 跨进程通信
    • Binder:用于应用与系统服务的高效通信。
    • HIDL/AIDL:解耦系统服务与厂商实现,支持向前兼容。
  • 安全边界:内核驱动作为用户空间与安全环境的桥梁,通过严格权限控制保障隔离性。
[应用进程] --Binder--> [keystore进程] --HIDL--> [KeymasterHAL进程] --ioctl--> [内核驱动] --> [TEE/HSM]↑                       |                         || (android.security.KeyStore) | (KeyStoreService)  | (厂商实现)用户空间                  用户空间                  用户空间              内核空间

应用代码示例

                 try {final String KEY_ALIAS = "myKeyAliasx";KeyStore keyStore;keyStore = KeyStore.getInstance("AndroidKeyStore");keyStore.load(null);// 检查密钥是否已存在,如果不存在则生成新的密钥对if (!keyStore.containsAlias(KEY_ALIAS)) {//生成密钥KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(KEY_ALIAS,KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY).setDigests(KeyProperties.DIGEST_SHA256).setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS).setKeySize(2048).build();KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");keyPairGenerator.initialize(spec);KeyPair keyPair = keyPairGenerator.generateKeyPair();}KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);PrivateKey privateKey = privateKeyEntry.getPrivateKey();KeyFactory factory = KeyFactory.getInstance(privateKey.getAlgorithm(), "AndroidKeyStore");KeyInfo keyInfo;//获取密钥信息keyInfo = factory.getKeySpec(privateKey, KeyInfo.class);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {int securityLevel = keyInfo.getSecurityLevel();if (securityLevel == KeyProperties.SECURITY_LEVEL_TRUSTED_ENVIRONMENT) {System.out.println("key is in trusted environment");} else if (securityLevel == KeyProperties.SECURITY_LEVEL_STRONGBOX) {System.out.println("key is in strongbox");} else {System.out.println("key is in software");}} else {boolean insideSecureHardware = keyInfo.isInsideSecureHardware();System.out.println("insideSecureHardware=" + insideSecureHardware);}// 签名Signature signature = Signature.getInstance("SHA256withRSA/PSS");signature.initSign(privateKey);signature.update("adgfdfd".getBytes("UTF-8"));byte[] sign = signature.sign();} catch (Exception e) {e.printStackTrace();}

相关文章:

android keystore源码分析

架构 Android Keystore API 和底层 Keymaster HAL 提供了一套基本的但足以满足需求的加密基元&#xff0c;以便使用访问受控且由硬件支持的密钥实现相关协议。 Keymaster HAL 是由原始设备制造商 (OEM) 提供的动态加载库&#xff0c;密钥库服务使用它来提供由硬件支持的加密服…...

【12】智能合约开发入门

12-1 在线合约开发 Cloud IDE简介 基本框架 Cloud IDE是BaaS合约平台提供的在线合约开发工具 IDE是一个去中心化应用&#xff08;Dapp&#xff09;&#xff0c;通过JavaScript SDK直接与区块链平台通信&#xff0c;进行合约部署和调用 核心功能 合约工程管理 合约编辑与编…...

web安全——分析应用程序

文章目录 一、确定用户输入入口点二、确定服务端技术三、解析受攻击面 一、确定用户输入入口点 在检查枚举应用程序功能时生成的HTTP请求的过程中&#xff0c;用户输入入口点包括&#xff1a; URL文件路径 通常&#xff0c;在查询字符?之前的URL部分并不视为用户输入入口&am…...

Wpf 之Generic.xaml

在 WPF 中&#xff0c;Generic.xaml 是一个特殊的资源文件&#xff0c;它会被自动加载&#xff0c;不需要显式添加。这是 WPF 的命名约定。当 WPF 初始化自定义控件时&#xff0c;它会专门查找这个名字的文件。 这个名字是硬编码在 WPF 框架中的&#xff0c;不能改变。 Generi…...

VidSketch:具有扩散控制的手绘草图驱动视频生成

浙大提出的VidSketch是第一个能够仅通过任意数量的手绘草图和简单的文本提示来生成高质量视频动画的应用程序。该方法训练是在单个 RTX4090 GPU 上进行的&#xff0c;针对每个动作类别使用一个小型、高质量的数据集。VidSketch方法使所有用户都能使用简洁的文本提示和直观的手绘…...

解锁C# XML编程:从新手到实战高手的蜕变之路

一、引言&#xff1a;XML 在 C# 中的关键地位 在 C# 开发的广袤领域中&#xff0c;XML&#xff08;可扩展标记语言&#xff0c;eXtensible Markup Language&#xff09;宛如一颗璀璨的明星&#xff0c;占据着举足轻重的地位。它以其独特的结构化和自描述特性&#xff0c;成为了…...

kafka-leader -1问题解决

一. 问题&#xff1a; 在 Kafka 中&#xff0c;leader -1 通常表示分区的领导者副本尚未被选举出来&#xff0c;或者在获取领导者信息时出现了问题。以下是可能导致出现 kafka leader -1 的一些常见原因及相关分析&#xff1a; 1. 副本同步问题&#xff1a; 在 Kafka 集群中&…...

超大规模分类(四):Partial FC

人脸识别任务里&#xff0c;通常利用全连接层&#xff0c;来做人脸的分类。会面临三个实际问题&#xff1a; 真实的人脸识别数据噪声严重真实的人脸识别数据存在严重的长尾分布问题&#xff0c;一些类别样本多&#xff0c;多数类别样本少人脸类别越来越多&#xff0c;全连接层…...

uniapp 小程序如何实现大模型流式交互?前端SSE技术完整实现解析

文章目录 一、背景概述二、核心流程图解三、代码模块详解1. UTF-8解码器&#xff08;处理二进制流&#xff09;2. 请求控制器&#xff08;核心通信模块&#xff09;3. 流式请求处理器&#xff08;分块接收&#xff09;4. 数据解析器&#xff08;处理SSE格式&#xff09;5. 回调…...

因子分析详解:从理论到MATLAB实战

内容摘要&#xff1a; 本文系统解析因子分析的核心原理与MATLAB实战&#xff0c;涵盖数学模型、载荷矩阵估计、因子旋转及得分计算。通过上市公司盈利能力、消费者偏好等案例&#xff0c;演示数据标准化、因子提取与解释的全流程&#xff0c;并提供完整代码实现。深入对比因子分…...

【组态PLC】基于三菱西门子S7-200PLC和组态王液料混合系统组态设计【含PLC组态源码 M016期】

控制要求 总体控制要求&#xff1a;如面板图所示&#xff0c;本装置为三种液体混合模拟装置&#xff0c;由液面传感器SL1、SL2、SL3&#xff0c;液体A、B、C阀门与混合液阀门由电磁阀YV1、YV2、YV3、YV4&#xff0c;搅匀电机M&#xff0c;加热器H&#xff0c;温度传感器T组成。…...

js:根据后端返回的数组取出每一个数组的keyword字段然后拼接成一个逗号分隔的字符串

问&#xff1a; 现在有一个el-select&#xff0c; 后端接口返回数据为keyword:xxx,referenceNum:1,tagId:132sf32fasdfaf组成的数组&#xff0c; 现在select是多选&#xff0c; 但是但我选择多个下拉框选项后&#xff0c;后端需要前端返回的数据tagIds字段需要时一个字符串…...

基于大模型的肺纤维化预测及临床方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 二、大模型技术概述 2.1 大模型的基本原理 2.2 大模型在医疗领域的应用现状 三、肺纤维化相关知识 3.1 肺纤维化的病因与发病机制 3.2 肺纤维化的临床症状与诊断方法 3.3 肺纤维化的治疗现状与挑战 四、大模型…...

7. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Ocelot 网关--路由

路由是API网关的核心功能&#xff0c;对系统性能和可靠性至关重要。路由通过定义规则&#xff0c;将客户端请求准确地转发到相应的后端服务&#xff0c;确保请求能够正确处理&#xff0c;简化了微服务架构中的服务调用逻辑。有效的路由配置能够提高系统的灵活性和可维护性。 一…...

【GESP】C++二级模拟 luogu-b3995, [GESP 二级模拟] 小洛的田字矩阵

GESP二级模拟题&#xff0c;多层循环、分支语句练习&#xff0c;难度★✮☆☆☆。 题目题解详见&#xff1a;https://www.coderli.com/gesp-2-luogu-b3995/ 【GESP】C二级模拟 luogu-b3995, [GESP 二级模拟] 小洛的田字矩阵 | OneCoderGESP二级模拟题&#xff0c;多层循环、分…...

监督学习——基于线性回归的波士顿房价预测:理论、实践与评估

基于线性回归的波士顿房价预测:理论、实践与评估 文章目录 基于线性回归的波士顿房价预测:理论、实践与评估一、引言二、线性回归基础理论2.1 线性回归原理2.2 线性回归在房价预测中的应用逻辑三、波士顿房价数据集介绍3.1 数据集概述3.2 特征说明3.3 目标变量四、波士顿房价…...

Selenium 调用模型接口实现功能测试

要使用 Selenium 调用模型接口实现功能测试,可按以下步骤进行: 1. 环境准备 安装 Selenium:使用 pip install selenium 安装 Selenium 库。安装浏览器驱动:根据使用的浏览器(如 Chrome、Firefox 等)下载对应的驱动,并将其添加到系统的环境变量中。例如,Chrome 浏览器需…...

回调函数的用法

回调函数的基本用法 回调函数是一种被作为参数传递给另一个函数的函数&#xff0c;接收回调函数作为参数的函数在合适的时候会调用这个回调函数。回调函数为代码提供了更高的灵活性和可扩展性&#xff0c;下面为你详细介绍回调函数的基本用法。 基本概念 回调函数的核心在于函…...

springboot实现文件上传到华为云的obs

一、前言 有时在项目中需要使用一些存储系统来存储文件&#xff0c;那么当项目要接入obs作为存储系统时&#xff0c;就会利用obs来进行文件的上传下载&#xff0c;具体实现如下。 二、如何通过obs实现文件的上传下载&#xff1f; 1.添加相关的obs的maven依赖。 <dependency…...

南京布局产业园剖析:成都树莓集团的战略逻辑

在数字产业飞速发展的当下&#xff0c;成都树莓集团在南京布局产业园&#xff0c;这一举措蕴含着深刻的战略考量&#xff0c;是基于对市场环境、产业趋势以及自身发展需求的综合研判。 一、政策利好与发展机遇 南京作为长三角地区的重要城市&#xff0c;在数字经济发展方面享有…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...