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