Wrong RSA PrivateKey KeyStore
Wrong RSA PrivateKey KeyStore
My app generates a KeyPair when it's opened. I can encrypt text with the PublicKey but when I try to decrypt it with the PrivateKey it throws InvalidKeyException.
KeyPair
PublicKey
PrivateKey
InvalidKeyException
Some Log.v debug:
Log.v
(...) V/Aliases: The public key created is [android.security.keystore.AndroidKeyStoreRSAPublicKey@1840131a]
(...) V/Aliases: The private key created is [android.security.keystore.AndroidKeyStoreRSAPrivateKey@37ad0430]
(...) V/Aliases: The public key used is [android.security.keystore.AndroidKeyStoreRSAPublicKey@1840131a]
(...) V/Aliases: The private key used is [android.security.keystore.AndroidKeyStoreRSAPrivateKey@37ad0430]
(...) V/Aliases: The private key [android.security.keystore.AndroidKeyStoreRSAPrivateKey@37ad0430] is incorrect
KeyPair generation:
KeyPair
try {
//Load KeyStore
keystore = KeyStore.getInstance("AndroidKeyStore");
keystore.load(null);
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException e) {
e.printStackTrace();
}
//KeyPair generation
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder("Test",KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.build());
kp = kpg.generateKeyPair();
Log.v("Aliases", "The public key created is [" + kp.getPublic() + "]");
Log.v("Aliases", "The private key created is [" + kp.getPrivate()+ "]");
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
Encryption function:
Encryption
//Removed try/catch
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry("Test", null);
PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey();
Log.v("Aliases", "The public key used is [" + publicKey + "]");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
bytes = cipher.doFinal(edittext.getText().toString().getBytes());
edittext.setText(Base64.encodeToString(bytes, Base64.DEFAULT));
Decryption function:
Decryption
//Removed try/catch
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry("Test", null);
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Log.v("Aliases", "The private key used is [" + privateKey + "]");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
String decrypted = new String(cipher.doFinal(Base64.decode(edittext.getText().toString(), Base64.DEFAULT)));
edittext.setText(decrypted);
//Removed the "try" part. This gets executed when cipher.init returns InvalidKeyException
catch (InvalidKeyException e) {
KeyStore.PrivateKeyEntry privateKeyEntry = null;
privateKeyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry("Test", null);
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Log.v("Aliases", "The private key [" + privateKey + "] is incorrect");
e.printStackTrace();
}
1 Answer
1
Don't do this:
Cipher cipher = Cipher.getInstance("RSA");
Always specify the full "algorithm/mode/padding" specification. For example,
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding");
Now you also need to tell AndroidKeyStore what encryption paddings you are permitting for your key. So add a setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) call in your call chain for KeyGenParameterSpec.Builder(...), i.e.
setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
KeyGenParameterSpec.Builder(...)
kpg.initialize(new KeyGenParameterSpec.Builder("Test",
KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.build());
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.