KeyStore简介

利用 Android KeyStore System,您可以在容器中存储加密密钥,从而提高从设备中提取密钥的难度。在密钥进入密钥库后,可以将它们用于加密操作,而密钥材料仍不可导出。此外,它提供了密钥使用的时间和方式限制措施,例如要求进行用户身份验证才能使用密钥,或者限制为只能在某些加密模式中使用。

密钥库系统由 KeyChain API 以及在 Android 4.3(API 级别 18)中引入的 Android 密钥库提供程序功能使用。本文说明了何时以及如何使用 Android 密钥库提供程序。

应用场景

1、 存储密匙:Android提供的这个KeyStore最大的作用就是不需要开发者去维护这个密匙的存储问题,相比起存储在用户的数据空间或者是外部存储器都更加安全。注意的是这个密匙随着用户清除数据或者卸载应用都会被清除掉。
2、得益于Android独立的一套密匙库系统,可以提高安全性

安全功能

Android 密钥库系统可以保护密钥材料免遭未经授权的使用。首先,Android 密钥库可以防止从应用进程和 Android 设备中整体提取密钥材料,从而避免了在 Android 设备之外以未经授权的方式使用密钥材料。其次,Android 密钥库可以让应用指定密钥的授权使用方式,并在应用进程之外强制实施这些限制,从而避免了在 Android 设备上以未经授权的方式使用密钥材料。

提取防范

Android 密钥库密钥使用两项安全措施来避免密钥材料被提取:

  • 密钥材料永不进入应用进程。通过 Android 密钥库密钥执行加密操作时,应用会将待签署或验证的明文、密文和消息馈送到执行加密操作的系统进程。如果应用进程受攻击,攻击者也许能使用应用密钥,但无法提取密钥材料(例如,在 Android 设备以外使用)。
  • 您可以将密钥材料绑定至 Android 设备的安全硬件,例如可信执行环境 (TEE) 和安全元素 (SE)。为密钥启用此功能时,其密钥材料永远不会暴露于安全硬件之外。如果 Android 操作系统受到攻击或者攻击者可以读取设备内部存储空间,攻击者也许能在 Android 设备上使用应用的 Android 密钥库,但无法从设备上提取这些数据。只有设备的安全硬件支持密钥算法、区块模式、填充方案和密钥有权使用的摘要的特定组合时,才可启用此功能。要检查是否为密钥启用了此功能,请获取密钥的 KeyInfo 并检查 KeyInfo.isInsideSecurityHardware() 的返回值。

密钥使用授权

为了避免在 Android 设备上以未经授权的方式使用密钥材料,在生成或导入密钥时 Android 密钥库会让应用指定密钥的授权使用方式。一旦生成或导入密钥,其授权将无法更改。然后,每次使用密钥时,都会由 Android 密钥库强制执行授权。这是一项高级安全功能,通常仅用于有以下要求的情形:在生成/导入密钥后(而不是之前或当中),应用进程受到攻击不会导致密钥以未经授权的方式使用。

支持的密钥使用授权可归为以下几个类别:

  • 加密:授权密钥算法、运算或目的(加密、解密、签署、验证)、填充方案、区块模式以及可与密钥搭配使用的摘要;
  • 时间有效性间隔:密钥获得使用授权的时间间隔;
  • 用户身份验证:密钥只能在用户最近进行身份验证时使用。请参阅要求进行用户身份验证才能使用密钥。

作为一项额外的安全措施,对于密钥材料位于安全硬件内部的密钥(请参阅 KeyInfo.isInsideSecurityHardware()),某些密钥使用授权可能由安全硬件实施,具体取决于 Android 设备。加密和用户身份验证授权可能由安全硬件实施。由于安全硬件一般不具备独立的安全实时时钟,时间有效性间隔授权不可能由其实施。

您可以使用 KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware() 查询密钥的用户身份验证授权是否由安全硬件实施。

选择密钥链或 Android 密钥库提供程序

在需要系统级凭据时请使用 KeyChain API。在应用通过 KeyChain API 请求使用任何凭据时,用户需要通过系统提供的 UI 选择应用可以访问已安装的哪些凭据。因此,在用户同意的情况下多个应用可以使用同一套凭据。

使用 Android 密钥库提供程序让各个应用存储自己的凭据,并且只允许应用自身访问。这样,应用可以管理仅能由自己使用的凭据,同时又可以提供等同于 KeyChain API 为系统级凭据提供的安全优势。这一方法不需要用户选择凭据。

使用 Android 密钥库提供程序

要使用此功能,请使用标准的 KeyStore 和 KeyPairGenerator 或 KeyGenerator 类,以及在 Android 4.3(API 级别 18)中引入的 AndroidKeyStore 提供程序。

AndroidKeyStore 注册为 KeyStore 类型以用于 KeyStore.getInstance(type) 方法,而在用于 KeyPairGenerator.getInstance(algorithm, provider) 和 KeyGenerator.getInstance(algorithm, provider) 方法时则注册为提供程序。

生成新私钥

生成新的 PrivateKey 要求您同时指定自签署证书具备的初始 X.509 属性。之后,您可以使用 KeyStore.setKeyEntry 将证书替换为由证书颁发机构 (CA) 签署的证书。

要生成密钥,请使用 KeyPairGenerator 和 KeyPairGeneratorSpec:

/** Generate a new EC key pair entry in the Android Keystore by* using the KeyPairGenerator API. The private key can only be* used for signing or verification and only with SHA-256 or* SHA-512 as the message digest.*/
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(alias,KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY).setDigests(KeyProperties.DIGEST_SHA256,KeyProperties.DIGEST_SHA512).build());KeyPair kp = kpg.generateKeyPair();

生成新密钥

要生成密钥,请使用 KeyGenerator 和 KeyGenParameterSpec。

使用密钥库条目

AndroidKeyStore 提供程序的使用通过所有的标准 KeyStore API 加以实现。

列出条目

通过调用 aliases() 方法列出密钥库中的条目:

/** Load the Android KeyStore instance using the the* "AndroidKeyStore" provider to list out what entries are* currently stored.*/
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
Enumeration<String> aliases = ks.aliases();

签署和验证数据

通过从密钥库提取 KeyStore.Entry 并使用 Signature API(例如 sign())签署数据:

/** Use a PrivateKey in the KeyStore to create a signature over* some data.*/
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {Log.w(TAG, "Not an instance of a PrivateKeyEntry");return null;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();

类似地,请使用 verify(byte[]) 方法验证数据:

/** Verify a signature previously made by a PrivateKey in our* KeyStore. This uses the X.509 certificate attached to our* private key in the KeyStore to validate a previously* generated signature.*/
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {Log.w(TAG, "Not an instance of a PrivateKeyEntry");return false;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initVerify(((PrivateKeyEntry) entry).getCertificate());
s.update(data);
boolean valid = s.verify(signature);

要求进行用户身份验证才能使用密钥

生成密钥或将密钥导入到 AndroidKeyStore 时,您可以指定密钥仅授权给经过身份验证的用户使用。用户使用安全锁定屏幕凭据(模式/PIN/密码、指纹)的子集进行身份验证。

这是一项高级安全功能,通常仅用于有以下要求的情形:在生成/导入密钥后(而不是之前或当中),应用进程受到攻击不会导致密钥被未经身份验证的用户使用。

如果密钥仅授权给经过身份验证的用户使用,可以将其配置为以下列两种模式之一运行:

  • 经过身份验证的用户可以在一段时间内使用密钥。在用户解锁安全锁定屏幕或使用 KeyguardManager.createConfirmDeviceCredentialIntent 流程确认其安全锁定屏幕凭据后,即可使用此模式中的所有密钥。每个密钥的授权持续时间各不相同,并由 setUserAuthenticationValidityDurationSeconds 在密钥生成或导入时指定。此类密钥只能在启用安全锁定屏幕时生成或导入(请参阅 KeyguardManager.isDeviceSecure())。在安全锁定屏幕停用(重新配置为“无”、“滑动”或不验证用户身份的其他模式)或被强制重置(例如由设备管理员执行)时,这些密钥将永久失效。
  • 用户身份验证会授权与某一密钥关联的特定加密操作。在此模式中,涉及此类密钥的每个操作都需要用户单独授权。目前,此类授权的唯一方式是指纹身份验证:FingerprintManager.authenticate。此类密钥只能在至少注册一个指纹时生成或导入(请参阅 FingerprintManager.hasEnrolledFingerprints)。一旦注册新指纹或取消注册所有指纹,这些密钥将永久失效。

更多参见:https://developer.android.com/training/articles/security-key-attestation?hl=zh-CN

Android KeyStore密钥存储相关推荐

  1. android keystore作用,如何使用Android KeyStore安全地存储任意字符串?

    我以可以使用AndroidKeyStore保护任意数据块为前提,并将其称为"键". 但是,我研究得越深,就越清楚地看到KeyStore API与与安全性相关的对象(证书,密钥规格, ...

  2. 安卓设置keychain_使用Android KeyChain安全存储对称密钥

    鉴于无法使用 Android KeyChain API存储对称密钥,以下是存储对称密钥的安全方法: 第一部分:密钥生成和存储 >生成symmetric_key >生成(private_ke ...

  3. android studio密钥库口令,Android应用开发Android Studio签名打包及根据keystore密钥获取SHA1安全码...

    本文将带你了解Android应用开发Android Studio签名打包及根据keystore密钥获取SHA1安全码,希望本文对大家学Android有所帮助. " 一.签名打包两种方式 1. ...

  4. Android KeyStore流程

    文章目录 一.Keystore 二.Keystore架构及接口函数 1. Keystore组件架构 2. IKeymasterDevice.hal中的几个重要接口函数 2.1 begin函数 2.2 ...

  5. 从 Secure Element 到 Android KeyStore

    忽如一夜春风来,智能手机来到每个人的手上,我们用它支付.理财.娱乐.工作.记录生活.存储私密信息.乘坐公共交通.开启家门.控制汽车....智能手机是如此的重要,不知天天把它拿在手上的你,是否关心过它是 ...

  6. ECDH KDF java_java-ECDH使用Android KeyStore生成的私钥

    我正在尝试使用由Android KeyStore Provider生成的私有代码在Android中实现ECDH. public byte[] ecdh(PublicKey otherPubKey) t ...

  7. java ecdh_java-ECDH使用Android KeyStore生成的私钥

    我正在尝试使用由Android KeyStore Provider生成的私有代码在Android中实现ECDH. public byte[] ecdh(PublicKey otherPubKey) t ...

  8. android+静态密钥,Android - 更安全地保存静态密钥

    转载请注明出处:https://blog.csdn.net/mythmayor/article/details/107228669 引言 在日常开发中我们经常需要保存一些私密的信息,例如加解密的密钥等 ...

  9. Keystore密钥库

    近来由于项目需要做Single Sign On, 研究了一下CAS(具体配置等下篇再介绍), 而这个CAS的配置最关键的不是CAS本身,而是数字证书,如何配置多台服务器之间的信任链接.因此,有必要把k ...

最新文章

  1. 实验二 164 张增进
  2. 进行短视频app开发工作时,可以加入它来保护青少年...
  3. Android 之小技巧
  4. Windows7 网上邻居设置
  5. Jupyter Notebook 代码自动补全功能
  6. 在那天的雪停息之前β
  7. 【Device Tree】设备树(一)——GPIO
  8. python常用函数中文_【python】python常用函数
  9. python中要使用导入全部的是什么符号-在python格式字符串中使用标点符号
  10. 利用数组实现栈java,用java编写出来:用数组实现一个栈
  11. Zabbix server is not running:the information displayed may not be current
  12. sql 新增加一列序号_取出上一条下一条的 sql语句
  13. jQuery中的gt和lt
  14. 回调函数透彻理解Java
  15. 租房减税30,房东加租300!
  16. 计算机卡和c盘东西多有关吗,电脑c盘东西装太多会卡吗
  17. Android 稳定性面试一文通
  18. 这所985【交通大学】成立电子与信息学部!计算机等专业包含在内!
  19. 惠勒延迟选择实验(转)
  20. 【Oracle】ORA-06553: PLS-306: wrong number or types of arguments in call to ‘存储过程‘

热门文章

  1. 本学期学校共开设了3门选修课,一个班有25位学生
  2. 传5G版iPhone SE将配双镜头摄像头并配备更大屏幕
  3. 大西北织梦模板网已测试
  4. 国内外机载雷达数据整理
  5. 管程的应用--读者写者问题(伪代码)
  6. 为远程工作人员提供21种组织工具
  7. vue H5跳转小程序
  8. 在js中用正则匹配中文
  9. 高防IP可以抵御哪些恶意攻击?
  10. IDEA 调试技巧,比 Eclipse 强太多了!