android.security.KeyStoreException: Unknown error On a rare number of devices

别等时光非礼了梦想. 提交于 2020-06-12 05:27:05

问题


I'm getting android.security.KeyStoreException: Unknown error On a rare number of devices with different Android Versions (6 - 8)

This is my key generation code:

final KeyPairGenerator keyGenerator = KeyPairGenerator
                        .getInstance(KeyProperties.KEY_ALGORITHM_RSA, 

ANDROID_KEY_STORE);

keyGenerator.initialize(new KeyGenParameterSpec.Builder(ALIAS,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setKeySize(2048)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                    .build());

return keyGenerator.generateKeyPair();

This is how I load the keyPair:

if (keyStore.containsAlias(ALIAS))
            {
                KeyStore.Entry entry = keyStore.getEntry(ALIAS, null);
                if (entry != null)
                {
                    if (entry instanceof KeyStore.PrivateKeyEntry)
                    {
                        Log.i(TAG, "KeyPair found.");
                        KeyStore.PrivateKeyEntry pke = (KeyStore.PrivateKeyEntry) entry;
                        Certificate cert = pke.getCertificate();

                        if (cert != null)
                        {
                            return new KeyPair(cert.getPublicKey(), pke.getPrivateKey());
                        }

                        Log.w(TAG, "Cert / Public Key is null");
                    }
                }
            }

This is my decryption code:

Cipher RSACipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");          

RSACipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(RSACipher.doFinal(base64.decode(textToDecrypt)), "UTF-8");

Here is a sample stracktrace of a failing decryption process:

Caused by javax.crypto.IllegalBlockSizeException
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
       at javax.crypto.Cipher.doFinal(Cipher.java:1736)
       at com.examplecompany.security.EncryptionController.decryptAsymmetric(EncryptionController.java:297)
       at com.example.crypto.android2.services.CryptoClass.decryptMessage(CryptoClass.java:684)
       at com.example.crypto.android2.services.CryptoClass.handleDecryption(CryptoClass.java:619)
       at com.example.crypto.android2.services.CryptoClass.doInBackgroundInternal(CryptoClass.java:450)
       at com.example.crypto.android2.services.CryptoClass.doInBackground(CryptoClass.java:165)
       at com.example.crypto.android2.services.CryptoClass.doInBackground(CryptoClass.java:84)
       at android.os.AsyncTask$2.call(AsyncTask.java:333)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

Caused by android.security.KeyStoreException: Unknown error
       at android.security.KeyStore.getKeyStoreException(KeyStore.java:1137)
       at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
       at javax.crypto.Cipher.doFinal(Cipher.java:1736)
       at com.examplecompany.security.EncryptionController.decryptAsymmetric(EncryptionController.java:297)
       at com.example.crypto.android2.services.CryptoClass.decryptMessage(CryptoClass.java:684)
       at com.example.crypto.android2.services.CryptoClass.handleDecryption(CryptoClass.java:619)
       at com.example.crypto.android2.services.CryptoClass.doInBackgroundInternal(CryptoClass.java:450)
       at com.example.crypto.android2.services.CryptoClass.doInBackground(CryptoClass.java:165)
       at com.example.crypto.android2.services.CryptoClass.doInBackground(CryptoClass.java:84)
       at android.os.AsyncTask$2.call(AsyncTask.java:333)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

It works well in 99.999% of all messages to be encrypted on thousands of devices, but sometimes it fails. Can you help me?


回答1:


Just found a solution for a similar issue on other question here in SO

I found my answer on the Android Issue Tracker, from what I understand, the unrestricted PublicKey, created to work around another known issue, becomes incompatible with the current Cipher. The work around for this is to specify an OAEPParameterSpec when the Cipher is initialized:

You need the following as a third argument to your Cipher init code

OAEPParameterSpec spec = new OAEPParameterSpec(
        "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);


RSACipher.init(Cipher.DECRYPT_MODE, privateKey, spec); // I added the same to the init in Cipher.ENCRYPT_MODE too


来源:https://stackoverflow.com/questions/49982508/android-security-keystoreexception-unknown-error-on-a-rare-number-of-devices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!