导入AES包装密钥至Keystore时触发不兼容用途异常
Android Keystore导入包装密钥报错:Incompatible purpose
问题重现
尝试将经RSA 3072位密钥包装的AES密钥导入Keystore,使用的Kotlin代码如下:
fun importWrappedJey(keySpec: KeySpec) { val spec = KeyGenParameterSpec.Builder(keySpec.alias, KeyProperties.PURPOSE_WRAP_KEY) .setDigests(KeyProperties.DIGEST_SHA256) .setCertificateNotBefore(keySpec.notBeforeDate.toDate()) .setCertificateNotAfter(keySpec.expireDate.toDate()) .setKeyValidityStart(keySpec.notBeforeDate.toDate()) .setKeyValidityEnd(keySpec.expireDate.toDate()) .build() val wrappedKeyEntry: WrappedKeyEntry = WrappedKeyEntry(keySpec.wrap, keySpec.wrappingKeyAlias, "RSA/ECB/OAEPPadding", spec) keyStore.setEntry(keySpec.alias, wrappedKeyEntry, null) }
执行keyStore.setEntry时触发错误:
android.security.KeyStoreException: Incompatible purpose (internal Keystore code: -3 message: In import_wrapped_key. Caused by: 0: In KeystoreSecurityLevel::upgrade_keyblob_if_required_with. 1: In utils::upgrade_keyblob_if_required_with: Calling km_op. 2: Error::Km(ErrorCode(-3))) (public error code: 13 internal Keystore code: -3)
排查结果
解密包装的密钥后,发现其用途仅包含加密(INTEGER 0)和解密(INTEGER 1):
[1] (1 elem) SET (2 elem) INTEGER 0 INTEGER 1
对应KeyPurpose枚举定义:
enum class KeyPurpose : uint32_t { ENCRYPT = 0, DECRYPT = 1, SIGN = 2, VERIFY = 3, DERIVE_KEY = 4, // since 3.0 WRAP_KEY = 5, // since 3.0 };
代码中使用的KeyProperties.PURPOSE_WRAP_KEY对应枚举值5,但当前密钥用途中没有该值。之前功能正常,现在疑惑是否需要为密钥添加WRAP_KEY用途。
参考文档(翻译)
密钥用途(Purpose)标签
密钥用途标签用于指定密钥允许执行的操作,每个用途对应一个整数标识:
- 0:加密(ENCRYPT)
- 1:解密(DECRYPT)
- 2:签名(SIGN)
- 3:验证(VERIFY)
- 4:派生密钥(DERIVE_KEY,Android 3.0及以上支持)
- 5:包装密钥(WRAP_KEY,Android 3.0及以上支持)
当导入密钥或生成密钥时,指定的用途必须与密钥实际支持的用途匹配,否则Keystore会抛出兼容性错误。
内容的提问来源于stack exchange,提问作者Nicote Ool
相关产品推荐
相关产品推荐

