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.

Popular posts from this blog

Moria Casán

How to make file upload 'Required' in Contact Form 7?

Quinn's Post Commonwealth War Graves Commission Cemetery