Java 将AndroidKeyStoreRSAPrivateKey强制转换为RSAPrivateKey
我将遵循以下教程:。它(松散地)与Google示例应用程序相关联: 我可以使用公钥加密我的数据,并且可以在运行棒棒糖的设备上解密。但是,我有一个运行棉花糖的Nexus 6,出现以下错误:Java 将AndroidKeyStoreRSAPrivateKey强制转换为RSAPrivateKey,java,android,cryptography,java-security,android-6.0-marshmallow,Java,Android,Cryptography,Java Security,Android 6.0 Marshmallow,我将遵循以下教程:。它(松散地)与Google示例应用程序相关联: 我可以使用公钥加密我的数据,并且可以在运行棒棒糖的设备上解密。但是,我有一个运行棉花糖的Nexus 6,出现以下错误: java.lang.RuntimeException: Unable to create application com.android.test: java.lang.ClassCastException: android.security.keystore.AndroidKeyStoreRSAPrivate
java.lang.RuntimeException: Unable to create application com.android.test: java.lang.ClassCastException: android.security.keystore.AndroidKeyStoreRSAPrivateKey cannot be cast to java.security.interfaces.RSAPrivateKey
以下是它崩溃的代码:
KeyStore.Entry entry;
//Get Android KeyStore
ks = KeyStore.getInstance(KeystoreHelper.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
// Weird artifact of Java API. If you don't have an InputStream to load, you still need to call "load", or it'll crash.
ks.load(null);
// Load the key pair from the Android Key Store
entry = ks.getEntry(mAlias, null);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;
//ERROR OCCURS HERE::
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
output.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
我不愿意把这归因于安卓m的古怪之处,因为我看不出java加密库会发生变化的原因。如果M版本出现,我们的应用程序立即在M上崩溃,我会有大麻烦
我做错了什么?错误明确地说您不能强制转换到RSAPrivateKey,那么有人知道从条目中获取RSAPrivateKey的更好方法吗
非常感谢。我还没有尝试过,但您应该能够将android.security.keystore.AndroidKeyStoreRSAPrivateKey单独转换为以下内容。这些应该是您需要的接口:
我通过从Cipher.getInstance和not转换到RSAprivateKey中删除提供程序,成功地实现了这一点
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
我不是100%,但我认为原因在于棉花糖从OpenSSL到BoringSSL的变化。
无论如何,上述方法适用于M及以下级别。我通过以下方法解决了此问题(除了上面的@James answer): 在安卓6.0上,您不应该使用“AndroidOpenSSL”创建密码,它将在密码初始化处使用“需要RSA私钥或公钥”进行解密而失败。只需使用Cipher.getInstance(“RSA/ECB/PKCS1Padding”)就可以了。问题
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey(); // Don't TypeCast to RSAPublicKey
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PrivateKey privateKey = privateKeyEntry.getPrivateKey(); // Don't TypeCast to RSAPrivateKey
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey(); // Don't TypeCast to RSAPublicKey
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PrivateKey privateKey = privateKeyEntry.getPrivateKey(); // Don't TypeCast to RSAPrivateKey
解密
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey(); // Don't TypeCast to RSAPublicKey
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
PrivateKey privateKey = privateKeyEntry.getPrivateKey(); // Don't TypeCast to RSAPrivateKey
现在在AOSP上打开:。此解决方案对棒棒糖有效。但在棉花糖上它抛出:java.security.InvalidKeyException:需要RSA私有还是公共key@resp78在安卓6.0上,您不应该使用“AndroidOpenSSL”创建密码,它将在密码初始化处使用“需要RSA私钥或公钥”进行解密而失败。只需使用Cipher.getInstance(“RSA/ECB/PKCS1Padding”)就可以了。适用于棉花糖和Android N preview 5。谢谢。您的解决方案不足以防止它在Andr 6上崩溃。我尝试了它,做了更多的事情设置encryptPadding:setEncryptionPaddings(KeyProperties.ENCRYPTION\u PADDING\u RSA\u PKCS1)替换为ENCRYPTION\u PADDING\u NONE,然后它就工作了。您应该使用什么提供程序?给出异常消息:需要RSA私钥或公钥。