我无法在 Android 上解密之前加密的字符串。问题主要出现在运行 Android 6 Marshmallow 的索尼设备(Xperia Z5 和 Xperia Z5 Compact)上。
android.security.KeyStoreException:目的不兼容
在执行最后一行时抛出(其中别名是存储 key 的名称)。
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKey);
KeyStore本身是通过
获取的KeyStore.getInstance("AndroidKeyStore");
key 通过以下方法生成:
private static void createKey(String alias, String subject, KeyStore keyStore, BigInteger serialNumber, Date startDate, Date endDate, String algorithm, String keyStoreProvider, Context context)
throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
if (keyStore.containsAlias(alias)) {
// Key already exists.
return;
}
// Generate keys.
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setSubject(new X500Principal(subject))
.setSerialNumber(serialNumber)
.setStartDate(startDate)
.setEndDate(endDate)
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm, keyStoreProvider);
generator.initialize(spec);
KeyPair keyPair = generator.generateKeyPair();
}
其中算法是“RSA”,keyStoreProvider 是“AndroidKeyStore”。
堆栈跟踪部分:
android.security.KeyStoreException: Incompatible purpose
at android.security.KeyStore.getKeyStoreException(KeyStore.java:636)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:716)
at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:53)
at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612)
at javax.crypto.Cipher.tryCombinations(Cipher.java:532)
at javax.crypto.Cipher.getSpi(Cipher.java:437)
at javax.crypto.Cipher.init(Cipher.java:815)
at javax.crypto.Cipher.init(Cipher.java:774)
异常导致java.security.InvalidKeyException: Keystore operation failed to be throw
我无法直接在我的设备上重现错误(崩溃信息来自 Crashlytics)。
遵循 KeyStore 的堆栈跟踪和代码:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/keystore/java/android/security/KeyStore.java
看来问题出在 Keymaster 层。
最佳答案
在Android Keystore System , purpose
引用如何使用 key 。非对称 key 的可能选项是:
- 签名和验证
- 加密与解密
- 按键包装(仅限 Android P+)
针对 SDK 23 更新的 Android Keystore 系统 API 确实允许您限制对您的 key 的建议(请参阅 KeyProperties
)。
新 API 的示例:
KeyGenParameterSpec.Builder keyGenParameterSpecBuilder = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(algorithmDefinition.keyLengthBit, algorithmDefinition.publicExponent))
.setRandomizedEncryptionRequired(meta.randomizedEncryptionRequired)
.setBlockModes(algorithmDefinition.blockMode)
.setUserAuthenticationRequired(meta.userAuthenticationRequired)
.setKeySize(algorithmDefinition.keyLengthBit);
可能存在设备错误,该设备运行 SDK 23 并且您使用旧 API,但设备要求您使用新 API,将 prupose 设置为您想要执行的操作?
关于安卓.security.KeyStoreException : Incompatible purpose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36551038/