Java Android加密RSA InvalidKeyException
亲爱的 我需要帮助来理解decryptString不起作用的原因,并抛出“java.security.InvalidKeyException:需要RSA私钥或公钥”。当调用encrypt方法时,我通过私钥/证书使用公钥 谢谢你的帮助Java Android加密RSA InvalidKeyException,java,android,security,encryption,rsa,Java,Android,Security,Encryption,Rsa,亲爱的 我需要帮助来理解decryptString不起作用的原因,并抛出“java.security.InvalidKeyException:需要RSA私钥或公钥”。当调用encrypt方法时,我通过私钥/证书使用公钥 谢谢你的帮助 public class KeysHandler { /*** * Generate and store in AndroidKeyStore a security KeyPair keys. * @param alias - Alia
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;
}
}
公共类密钥处理程序{
/***
*生成并在AndroidKeyStore中存储安全密钥对密钥。
*@param alias-创建密钥的别名。
*@return-KeyPair对象具有:私钥和公钥。
*/
公共静态密钥对生成器密钥对(字符串别名){
密钥对kp=null;
如果(别名!=null){
试一试{
KeyPairGenerator kpg=KeyPairGenerator.getInstance(KeyProperties.KEY_算法_RSA,“AndroidKeyStore”);
kpg.initialize(新的KeyGenParameterSpec.Builder(别名,
KeyProperties.PURPOSE\u符号|
KeyProperties.PURPOSE\u验证|
KeyProperties.PURPOSE\u加密|
KeyProperties.PURPOSE(解密)
.setEncryptionPaddings(KeyProperties.ENCRYPTION\u PADDING\u RSA\u PKCS1)
.build());
kp=kpg.generateKeyPair();
}catch(NoSuchProviderException | NoSuchAlgorithmException | InvalidalgorithParameterException ex){
kp=null;
}
}
返回kp;
}
公共静态字符串加密字符串(字符串别名、字符串文本加密){
字符串加密文本=null;
试一试{
KeyStore KeyStore=KeyStore.getInstance(“AndroidKeyStore”);
keyStore.load(null);
KeyStore.PrivateKeyEntry PrivateKeyEntry=(KeyStore.PrivateKeyEntry)KeyStore.getEntry(别名,null);
//加密文本
if(textToEncypt!=null&&textToEncypt.length()>0){
密码输入=Cipher.getInstance(“RSA/ECB/PKCS1PANDING”、“AndroidOpenSSL”);
input.init(Cipher.ENCRYPT_模式,privateKeyEntry.getCertificate().getPublicKey());
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
CipherOutputStream CipherOutputStream=新CipherOutputStream(
输出流,输入);
cipherOutputStream.write(textToEncrypt.getBytes(“UTF-8”);
cipherOutputStream.close();
字节[]VAL=outputStream.toByteArray();
cipheredText=Base64.encodeToString(VAL,Base64.DEFAULT);
}
}捕获(例外e){
加密文本=空;
}
返回密文;
}
公共静态字符串解密字符串(字符串别名、字符串加密文本){
字符串明文=空;
试一试{
KeyStore KeyStore=KeyStore.getInstance(“AndroidKeyStore”);
keyStore.load(null);
KeyStore.PrivateKeyEntry PrivateKeyEntry=(KeyStore.PrivateKeyEntry)KeyStore.getEntry(别名,null);
密码输出=Cipher.getInstance(“RSA/ECB/PKCS1Padding”、“AndroidOpenSSL”);
init(Cipher.DECRYPT_模式,privateKeyEntry.getPrivateKey());
CipherInputStream CipherInputStream=新的CipherInputStream(
新的ByteArrayInputStream(Base64.decode(cipheredText,Base64.DEFAULT)),输出);
ArrayList值=新的ArrayList();
int-nextByte;
而((nextByte=cipherInputStream.read())!=-1){
添加((字节)下一个字节);
}
byte[]bytes=新字节[values.size()];
for(int i=0;i
尝试忽略密码提供程序:
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
其次,您可以首先实例化提供程序以确保其正常工作,然后将其作为第二个参数传递给
Cipher.getInstance()。
第二个参数可以是字符串(提供程序名称)或提供程序(对象)。使用第二个可能会使调试更容易。@FrederikHV真的很感谢,省略“AndroidOpenSSL”时,它起到了很好的效果。祝你一周愉快!你遗漏了什么?在加密和解密中,两个地方都省略了吗?谢谢。@sandeepmaram,无论你在哪里调用Cipher.getInstance