我无法在Android上解密以前加密的字符串。问题主要发生在运行Android 6 Marshmallow的索尼设备(Xperia Z5和Xperia Z5 Compact)上。
android.security.KeyStoreException:不兼容的目的
执行最后一行时抛出(其中别名是存储键的名称)。
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");
密钥由以下方法生成:
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:无法抛出密钥库操作。
我无法直接在我的设备上重现错误(广告信息来自Crashlytics)。
遵循KeyStore的堆栈跟踪和代码:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/keystore/java/android/security/KeyStore.java
似乎问题出在Keymaster图层上。
答案 0 :(得分:1)
在Android Keystore System中,purpose
引用了如何使用密钥。非对称密钥的可能选项是:
更新后的Android Key Keystore System API 23允许您限制密钥的建议(参见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,将该设置设置为您想要做的事情?