How come I cannot perform multiple keystore cipher decryptions on Samsung S6 and S7?
Asked Answered
J

1

10

I have found an issue that appears to be affecting some Samsung(so far) devices only. Here is the sudo:

  • initialize cipher1 and cipher2
  • decrypt using cipher1
  • decrypt using cipher2

IllegalBlockSizeException

Basically if I am holding on to one cipher, while decryption another in between trying to decrypt the other, we receive the exception.

We tried on a Nexus 6P, Nexus 5X, Note 4 (No issue) We saw the issue on (S7, S7 Edge, S6)

Code:

public void createKey(String keyName) {
        KeyPairGenerator generator = null;
        try {
            generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            Log.e("MainActivity", e.getMessage());
            e.printStackTrace();
        }

        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
                keyName,
                KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                .build();
        try {
            generator.initialize(spec);
        } catch (InvalidAlgorithmParameterException e) {
            Log.e("MainActivity", e.getMessage());
        }

        generator.generateKeyPair();
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        createKey("Key");
        createKey("Key1");

        KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
        ks.load(null);
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("Key", null);
        PrivateKey privateKey = (PrivateKey) privateKeyEntry.getPrivateKey();

        Cipher c;
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
            c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        } else {
            c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        }
        c.init(Cipher.DECRYPT_MODE, privateKey);

        mCancellationSignal = new CancellationSignal();



        String ecryptedS1 = doEncription("Key1");
        KeyStore ks1 = KeyStore.getInstance("AndroidKeyStore");
        ks1.load(null);
        KeyStore.PrivateKeyEntry privateKeyEntry1 = (KeyStore.PrivateKeyEntry) ks1.getEntry("Key1", null);
        PrivateKey privateKey1 = (PrivateKey) privateKeyEntry1.getPrivateKey();

        Cipher c1;
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
            c1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        } else {
            c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        }
        c1.init(Cipher.DECRYPT_MODE, privateKey1);

        String org = "";
        try {
            org = new String(c1.doFinal(Base64.decode(ecryptedS1, Base64.DEFAULT|Base64.NO_WRAP)));
            Log.d("MainActivity", "org key1" + org);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        org = null;
        try {
            org = new String(c.doFinal(Base64.decode(doEncription("Key"), Base64.DEFAULT|Base64.NO_WRAP)));
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
    }

Exception:

10-04 14:29:13.919 15568-15568/com.example.rollandliu.decryption W/System.err: javax.crypto.IllegalBlockSizeException
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:486)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at javax.crypto.Cipher.doFinal(Cipher.java:1502)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at com.example.rollandliu.decryption.MainActivity$3.onClick(MainActivity.java:248)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.view.View.performClick(View.java:5702)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.widget.TextView.performClick(TextView.java:10885)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.view.View$PerformClick.run(View.java:22533)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.os.Looper.loop(Looper.java:158)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7229)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: Caused by: android.security.KeyStoreException: Invalid operation handle
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.security.KeyStore.getKeyStoreException(KeyStore.java:940)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:473)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err:     ... 12 more
Jugendstil answered 4/10, 2016 at 18:44 Comment(2)
Post your (relevant) code here. We do not go "outside" to download it.Argot
Code posted, thanksJugendstil
O
11

It's a little outdated, but I'll post an answer here just in case some good folk will be trying to solve that problem.
Samsung devices have different implementation of Cipher class running in their JVM and in my case I only had to make operations with it synchronized.
It solved issue for me, so I may take a guess that Samsung's Cipher is not thread safe. Cheers!

Outflow answered 12/4, 2018 at 5:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.