I have found an issue that appears to be affecting some Samsung(so far) devices only. Here is the sudo:
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
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With