Android加密RSA InvalidKeyException [英] Android Encryption RSA InvalidKeyException
问题描述
亲爱的
我需要帮助来理解为什么deleteString不起作用并抛出"java.security.InvalidKeyException:需要RSA私钥或公钥".当调用加密方法时,我使用私钥/证书中的公钥.
I need help to understand why decryptString doesn't work and throw "java.security.InvalidKeyException: Need RSA private or public key". When call encrypt method, i use public key by the private key/certificate.
感谢您的帮助!
public class KeysHandler {
/***
* Generate and store in AndroidKeyStore a security KeyPair keys.
* @param alias - Alias to create the key.
* @return KeyPair object with: private and public key.
*/
public static KeyPair generateKeyPair(String alias) {
KeyPair kp = null;
if (alias != null) {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_SIGN |
KeyProperties.PURPOSE_VERIFY |
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build());
kp = kpg.generateKeyPair();
} catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidAlgorithmParameterException ex) {
kp = null;
}
}
return kp;
}
public static String encryptString(String alias, String textToEncrypt) {
String cipheredText = null;
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
// Encrypt the text
if(textToEncrypt != null && textToEncrypt.length() > 0) {
Cipher input = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
input.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, input);
cipherOutputStream.write(textToEncrypt.getBytes("UTF-8"));
cipherOutputStream.close();
byte[] vals = outputStream.toByteArray();
cipheredText = Base64.encodeToString(vals, Base64.DEFAULT);
}
} catch (Exception e) {
cipheredText = null;
}
return cipheredText;
}
public static String decryptString(String alias, String cipheredText) {
String clearText = null;
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipheredText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
clearText = new String(bytes, 0, bytes.length, "UTF-8");
} catch (Exception e) {
clearText = null;
}
return clearText;
}
}
推荐答案
尝试省略密码提供者:
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
第二,您可以首先实例化提供程序以确保其有效,然后将其作为第二个参数传递给 Cipher.getInstance().
第二个参数可以是String(提供者名称))或提供者(对象).使用第二个可以使调试更加容易.
Secondly, you can instantiate the provider first to make sure that works, then pass it along as the second argument to Cipher.getInstance().
The second argument can be either a String (provider name) or a Provider (object). Using the second might make debugging easier.
这篇关于Android加密RSA InvalidKeyException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!