Android Keystore System

[ 译文原文:Android Keystore System ]
Android Keystore system 允许您将加密密钥存储在容器中,以使其难以从设备中提取。一旦密钥在密钥库中,它们可用于加密操作, key material保持不可导出。此外,Android Keystore system还提供了限制密钥何时和如何使用的功能,例如要求密钥使用的用户认证或限制密钥仅在某些加密模式下使用。

Keystore system 被用于 Keychain API 以及在 Android 4.3中引入的AndroidKeystore功能 ,本文档介绍了何时以及如何使用 AndroidKeystore

Security 功能


Android Keystore系统保护 key material 免受未经授权的使用。首先,Android Keystore通过防止从应用程序进程和Android设备整体上提取 key material,减轻了 key material 在Android设备之外未经授权的使用。其次,在Android设备上,Android KeyStore指定了密钥在一个应用程序内授权使用,然后在应用程序进程之外被限制使用,从而减轻了Android设备上未经授权而使用 key material的情况。

预防 key material 的提取

保护Android Keystore密钥的 key material 不被抽取的2种措施:

  • key material从不进入应用进程。
    当应用程序使用Android Keystore获得密钥执行加密操作时,明文,密文和要签名或验证的消息被送到执行密码操作的系统进程。如果应用程序的进程受到威胁,攻击者可能可以使用该应用获取到的密钥,但无法提取 key material(例如,在Android设备之外使用)。

  • Key material被允许绑定到Android设备的安全硬件(例如,可信赖执行环境(TEE)、安全元素(SE))。
    当这个功能被用于密钥时,Key material不会被暴露在安全硬件外。这个功能虽然保证了Key material不被提取,但是如果Android OS被破环或者攻击者可以读取设备的内部存储,则其就可以在设备上获取并使用应用程序存储在AndroidKeystore中的密钥。而且重要的一点是,密钥通常是算法、block mod、填充模式、摘要的特殊组合,只有当这个组合被被设备的安全硬件所支持时,这个功能才能被启用,这是关键前提。如果要检查一个密钥是否适用于 Android设备的安全硬件功能,可以获取密钥的 KeyInfo 对象,并且检查 KeyInfo.isInsideSecurityHardware() 的返回值。

密钥的使用权限

为了避免在Android设备上密钥被未经授权的使用,AndroidKeystore建议应用程序在生成或者获取密钥之前做一次特殊的密钥授权,只有通过验证的用户才能使用密钥,而一旦密钥被应用程序生成或者获取之后,其使用者是谁则不属于AndroidKeystore功能范畴。

支持的密钥的授权分为以下几类:

  • 密码学:授权密钥算法,操作或目的(加密,解密,签名,验证),填充方案,块模式,可以使用密钥的摘要
  • 时间有效性间隔:密钥被授权使用的时间间隔
  • 用户认证:该密钥只能在用户最近得到认证后才能使用,参考 Requiring User Authentication For Key Use.

作为一项额外的安全措施,对于Key material在安全硬件内的密钥(参见 KeyInfo.isInsideSecurityHardware()),依赖于Android设备的不同,一些密钥的授权(密码组成)可能由安全硬件实施。加密和用户认证授权可能由安全硬件实施,时间的有效期则不太可能由安全硬件实施,因为安全硬件通常不具有独立的安全实时时钟。
密钥的用户认证授权是否由安全硬件实施,可以使用查询:KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()

Keychain 和 Android Keystore 比较


如果您想要全系统的凭据时,使用KeyChain,当通过KeyChain API请求使用任何凭据时,用户可以通过系统提供的UI来选择访问哪些已安装的凭据,这允许几个应用程序在用户的同意下使用相同的凭据集。

使用AndroidKeystore可以让个别应用程序存储自己的凭据,只有其本身可以访问,同时具有和KeyChain Api为系统级凭据提供的安全优势。此方法不需要用户交互选择凭据。

Android Keystore 的使用


要使用此功能,你可以使用属于AndroidKeyStore在Android 4.3(API18)引入的标准类 KeyStoreKeyPairGenerator / KeyGenerator
使用 KeyStore.getInstance(type)方法,AndroidKeyStore被注册为一个KeyStore类型,并且作为一个provider被用于 KeyPairGenerator.getInstance(algorithm, provider)KeyGenerator.getInstance(algorithm, provider) 方法。

在AndroidKeyStore中生成一个新的 Private Key

/*
 * 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();

在AndroidKeyStore中生成一个新的 Secret Key

和上面类似,但是使用的是KeyGeneratorKeyGenParameterSpec

使用密钥库

获取密钥库List

/*
 * 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();

签署和验证数据

sign data

/*
 * 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 data

/*
 * 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 /密码,指纹)的子集对用户进行身份验证。

当一个密钥被授权只有在用户被认证的情况下才被使用,它被配置为以两种模式之一进行操作:

  1. 用户认证授权使用密钥一段时间。

    一旦用户解锁了安全锁定屏幕,或者使用该KeyguardManager.createConfirmDeviceCredentialIntent 流程确认了其安全的锁定屏幕凭证,该模式中的所有键都将被授权使用 。授权保持有效的持续时间特定于每个密钥,如在密钥生成或导入期间使用setUserAuthenticationValidityDurationSeconds所指定的。

    如果只是启动了安全锁定屏幕,没有解锁过,则只能生成或者导入密钥(请参阅 KeyguardManager.isDeviceSecure())。

    如果一旦禁用安全锁定屏幕(重新配置为无,滑动或其他不认证用户的模式)或强制重置(例如由设备管理员处理),这些密钥将永久失效。

  2. 用户认证授权 与一个密钥相关联的 特定加密操作。

    在这种模式下,涉及这种密钥的每个操作必须由用户单独授权。目前,这种授权的唯一手段是指纹认证: FingerprintManager.authenticate。只有至少有一个指纹被注册才可以生成或导入这些密钥(见 FingerprintManager.hasEnrolledFingerprints)。一旦新的指纹被注册或者所有指纹都被取消注册,这些密钥将永久失效。

AndroidKeyStore支持的算法


  • Cipher
  • KeyGenerator
  • KeyFactory
  • KeyPairGenerator
  • Signature
  • SecretKeyFactory

Cipher

AlgorithmSupported (API Levels)Notes
AES/CBC/NoPadding23+
AES/CBC/PKCS7Padding23+
AES/CTR/NoPadding23+
AES/ECB/NoPadding23+
AES/ECB/PKCS7Padding23+
AES/GCM/NoPadding23+Only 12-byte long IVs supported.
RSA/ECB/NoPadding18+
RSA/ECB/PKCS1Padding18+
RSA/ECB/OAEPWithSHA-1AndMGF1Padding23+
RSA/ECB/OAEPWithSHA-224AndMGF1Padding23+
RSA/ECB/OAEPWithSHA-256AndMGF1Padding23+
RSA/ECB/OAEPWithSHA-384AndMGF1Padding23+
RSA/ECB/OAEPWithSHA-512AndMGF1Padding23+
RSA/ECB/OAEPPadding23+

KeyGenerator

AlgorithmSupported (API Levels)Notes
AES23+Supported sizes: 128, 192, 256
HmacSHA123+
  • Supported sizes: 8–1024 (inclusive), must be multiple of 8
  • Default size: 160
    HmacSHA22423+
    • Supported sizes: 8–1024 (inclusive), must be multiple of 8
    • Default size: 224
      HmacSHA25623+
      • Supported sizes: 8–1024 (inclusive), must be multiple of 8
      • Default size: 256
        HmacSHA38423+
        • Supported sizes: 8–1024 (inclusive), must be multiple of 8
        • Default size: 384
          HmacSHA51223+
          • Supported sizes: 8–1024 (inclusive), must be multiple of 8
          • Default size: 512

            KeyFactory

            AlgorithmSupported (API Levels)Notes
            EC23+Supported key specs: KeyInfo (private key only), ECPublicKeySpec (public key only), X509EncodedKeySpec (public key only)
            RSA23+Supported key specs: KeyInfo (private key only), RSAPublicKeySpec (public key only), X509EncodedKeySpec (public key only)

            KeyStore

            KeyStore supports the same key types as KeyPairGenerator and KeyGenerator.

            KeyPairGenerator

            AlgorithmSupported (API Levels)Notes
            DSA19–22
            EC23+
            • Supported sizes: 224, 256, 384, 521
            • Supported named curves: P-224 (secp224r1), P-256 (aka secp256r1 and prime256v1), P-384 (aka secp384r1), P-521 (aka secp521r1)

            Prior to API Level 23, EC keys can be generated using KeyPairGenerator of algorithm “RSA” initialized KeyPairGeneratorSpec whose key type is set to “EC” using setKeyType(String). EC curve name cannot be specified using this method – a NIST P-curve is automatically chosen based on the requested key size.

            RSA18+
            • Supported sizes: 512, 768, 1024, 2048, 3072, 4096
            • Supported public exponents: 3, 65537
            • Default public exponent: 65537

            Signature

            AlgorithmSupported (API Levels)Notes
            MD5withRSA18+
            NONEwithECDSA23+
            NONEwithRSA18+
            SHA1withDSA19–22
            SHA1withECDSA19+
            SHA1withRSA18+
            SHA1withRSA/PSS23+
            SHA224withDSA20–22
            SHA224withECDSA20+
            SHA224withRSA20+
            SHA224withRSA/PSS23+
            SHA256withDSA19–22
            SHA256withECDSA19+
            SHA256withRSA18+
            SHA256withRSA/PSS23+
            SHA384withDSA19–22
            SHA384withECDSA19+
            SHA384withRSA18+
            SHA384withRSA/PSS23+
            SHA512withDSA19–22
            SHA512withECDSA19+
            SHA512withRSA18+
            SHA512withRSA/PSS23+

            SecretKeyFactory

            AlgorithmSupported (API Levels)Notes
            AES23+Supported key specs: KeyInfo
            HmacSHA123+Supported key specs: KeyInfo
            HmacSHA22423+Supported key specs: KeyInfo
            HmacSHA25623+Supported key specs: KeyInfo
            HmacSHA38423+Supported key specs: KeyInfo
            HmacSHA51223+Supported key specs: KeyInfo
            • 0
              点赞
            • 0
              收藏
              觉得还不错? 一键收藏
            • 0
              评论
            评论
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

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

            抵扣说明:

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

            余额充值