Java Android加密RSA InvalidKeyException

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

亲爱的

我需要帮助来理解decryptString不起作用的原因,并抛出“java.security.InvalidKeyException:需要RSA私钥或公钥”。当调用encrypt方法时,我通过私钥/证书使用公钥

谢谢你的帮助

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