Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 414
Mr_E Avatar asked Oct 04 '16 18:10

Mr_E


1 Answers

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!

like image 131
Alviere Avatar answered Jan 02 '23 13:01

Alviere