44

私はこのチュートリアルに従っています: How to use the Android Keystore to store passwords and other sensitive information . これは (大まかに) Google サンプル アプリBasicAndroidKeyStoreと結びついています。

公開鍵を使用してデータを暗号化し、Lollipop を実行しているデバイスで復号化できます。ただし、マシュマロを実行している Nexus 6 があり、これがクラッシュしてエラーが発生します。

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);

Java暗号ライブラリが変更された理由が見当たらないので、これをAndroid Mの奇妙さに分類するのは気が進まない. M のリリースが近づいてきて、アプリがすぐに M でクラッシュした場合、私は大変なことになります。

私は何か間違ったことをしていますか?このエラーは、RSAPrivateKey にキャストできないことを明確に示しているため、エントリから RSAPrivateKey を取得するより良い方法を知っている人はいますか?

大変感謝します。

4

4 に答える 4

63

プロバイダーを Cipher.getInstance から削除し、RSAprivateKey にキャストしないことで、これを機能させることができました。

KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;

Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());

私は 100% ではありませんが、この理由は、マシュマロが OpenSSL から BoringSSL に変更されたためだと思います。 https://developer.android.com/preview/behavior-changes.html#behavior-apache-http-client

とにかく、上記はM以下で機能しました。

于 2015-09-10T10:10:16.657 に答える
14

問題

  1. 「 java.security.PrivateKeyから java.security.interfaces.RSAPrivateKey および「java.security.PublicKeyからjava.security.interfaces.RSAPublicKey を解析しようとしています。そのため、ClassCastException が発生しています。

解決

  1. キーを解析する必要はありません。暗号化と復号化に「 java.security.PrivateKey」と「java.security.PublicKey 」を直接使用できます。

暗号化

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
于 2017-02-06T10:30:39.123 に答える