BadPaddingException RSA在java中加密然后解密

BadPaddingException RSA在java中加密然后解密,java,encryption,cryptography,Java,Encryption,Cryptography,我得到了一个RSA公钥和一个带有OAEP SHA-256填充的RSA私钥。我试图简单地加密一个随机字符串,然后解密它,以断言结果与原始字符串相等 这是我得到的公钥: -----BEGIN RSA PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8tiBtDmkeS/ruY3rrkq dz6Lc6XWFRbI/GjPtIokrtpM+Ujyv6wX8TBqY8e03gzh+eE7VUyEVPapDnceAqgJ ZQah2h

我得到了一个RSA公钥和一个带有OAEP SHA-256填充的RSA私钥。我试图简单地加密一个随机字符串,然后解密它,以断言结果与原始字符串相等

这是我得到的公钥:

-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8tiBtDmkeS/ruY3rrkq
dz6Lc6XWFRbI/GjPtIokrtpM+Ujyv6wX8TBqY8e03gzh+eE7VUyEVPapDnceAqgJ
ZQah2h+N5AEQKqNDM4/1to1V0F+m1ISR7CIUU8dvU+bPk67DU5VkEtLxf+mW8/es
hy0u6oSB04WCDPNnh+9GDF7tN7lOzBH1FxKPWIb5Gqg6GoXS+KgvQhYEk0TajIBk
+mefzTv1D4HJlhFYybgY+/p3k4P2kM5HnbEtoVpz/PL9+94YVp5RBHTQHmk/3SAX
RkPP34IjY6LZqTJGWQGxc64Qci54ZJsq4wSTXvfdHgUWz7eX+v1jA+GLjFExNcYZ
nQIDAQAB
-----END RSA PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAUQiHdHuMBCnF
P/7RQoRWrp62dGWQLDLP9l+3KUMlSPheN2R5jHDZ/WEGJGF2WYKxaQvv5XCocdnt
uxVZTNM1PVyduokJaJzrSIj+jGWDd4hTWvVoS3vhds8u6W0jD3M4ayrF6c7NYuHc
tE5YLLIgK1DTn+ZZCr3VGbScISDJ/WPx3+1YTNQDvm+T7MfjhetJqqzWIsunMUiw
nQOQvkdjCVWpk+L10SaMrezixtIS5wfpOTjGIZ0w5VunvtsPxg1TkuvGURa9S3rS
7D3uhDPY+V8UDMpBPso3j7TGD5axlBJcpavWeF8qde3sWztmqUFQ3JDypZWGSAe2
d8e4mY65AgMBAAECggEAal8nwYxbHZnb5L892U7aVfuly7Nbzb+0pzRVwsBu5DuV
LL+kslpMvTYZqUUMJ2LhF/HLaXhVtMWsTYLSDx+gHu1+wbtAOtUDHlxzcaAEMhA2
dix0WqiNr6qAdCkmdWMBTu5vrSJigVW1KdcNElY+e+6ZeUQTK6L2Vt0t+cGVGkM4
K5PdHcGLR1BiAf3k4BguHE4TGGnqN9dF5Rn9nPP6C7QihWzGn15efD2dAXn3Kbho
dMIRgyYiO7uXPm2LrIjtldYb8tPus+V9SWT4hcgnJZrtd9atkqZrJ3dhQf9ZetGs
UwTCzHJ169NNbVyrjCbcy4Uht8Na+t/94Im9hI8n0QKBgQDO6tYnwh1hPg3E+4DY
xCiDAp7v3afJIvC9a1sBtif8KkzZTYH31ww+PRcfDPQUlk/MIDie0u6xIawnBYkC
oN1u9erojcvQbBP0GFylP5hNxYZbI7gPA/7AiGRxyezZPOiVMwdd5fCM7Wv4kucr
c1JCcvtPoDQcFFZOfI+wqqdWnQKBgQDt745Pvckt7/XL7wbfv4BV+cwpLNjc4/3k
ajOLtasgpT8mc0gUH2ejHhpkuhjSUpSTrlFB8EN1kAwmBYy0GOoO9967hm6twmqk
Q5L3OHJ96pYkf1rbyXNE1N7inh5Z3M1H5ONIaliAYLHXOzKsZvI5eUdKAJdSqFLo
uvVCwr4PzQKBgG6W3rzDJ9a4Rr24OgYg2RIkTXQgALQko4xpm2tPwxEoPoiJv2QK
ILYHCpuC3dU+/Qk5U2m3jPFI8OyuLask9RSABPwkBQGxMfztJF8BnVI7tvJxJceI
uBiJDT4v0RHOVvSfIFnUMnvvzRw+z6TObvGq6JyHIDK9v98U/etLWkKVAoGAIIxF
lmjqzUrm/8ep1A+5OYmbQQKug8D4aTeR54mpaCTSt6rLcF0/axPiHmdKn/LF+lG9
MdzxDXLwBn952OUTl4qWwGZKW6Cdv+yyfPkOyGS/tyxovGoZR5ArESr6Eebfefc4
lB5gDuerTDr/2o+WkQAjHV9pU9hMxyNUC5biMv0CgYEAiDlw8lBf3cQs6FxNXs9t
whWpfL0yY7WAONvhfFB0Dpsz52gGDCYRvJekGRz6jOlKDuXJ+Mm1AX4BaufMETI5
QseZxtVPIn+BXm0A1x8w/DifmE1JqQZmPCQPOh3eLx5nSn9LKGIbMgd17mfH3HhU
8WX2mzWjmRA3C/CzdGfCKSk=
-----END PRIVATE KEY-----
这是我得到的私钥:

-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8tiBtDmkeS/ruY3rrkq
dz6Lc6XWFRbI/GjPtIokrtpM+Ujyv6wX8TBqY8e03gzh+eE7VUyEVPapDnceAqgJ
ZQah2h+N5AEQKqNDM4/1to1V0F+m1ISR7CIUU8dvU+bPk67DU5VkEtLxf+mW8/es
hy0u6oSB04WCDPNnh+9GDF7tN7lOzBH1FxKPWIb5Gqg6GoXS+KgvQhYEk0TajIBk
+mefzTv1D4HJlhFYybgY+/p3k4P2kM5HnbEtoVpz/PL9+94YVp5RBHTQHmk/3SAX
RkPP34IjY6LZqTJGWQGxc64Qci54ZJsq4wSTXvfdHgUWz7eX+v1jA+GLjFExNcYZ
nQIDAQAB
-----END RSA PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAUQiHdHuMBCnF
P/7RQoRWrp62dGWQLDLP9l+3KUMlSPheN2R5jHDZ/WEGJGF2WYKxaQvv5XCocdnt
uxVZTNM1PVyduokJaJzrSIj+jGWDd4hTWvVoS3vhds8u6W0jD3M4ayrF6c7NYuHc
tE5YLLIgK1DTn+ZZCr3VGbScISDJ/WPx3+1YTNQDvm+T7MfjhetJqqzWIsunMUiw
nQOQvkdjCVWpk+L10SaMrezixtIS5wfpOTjGIZ0w5VunvtsPxg1TkuvGURa9S3rS
7D3uhDPY+V8UDMpBPso3j7TGD5axlBJcpavWeF8qde3sWztmqUFQ3JDypZWGSAe2
d8e4mY65AgMBAAECggEAal8nwYxbHZnb5L892U7aVfuly7Nbzb+0pzRVwsBu5DuV
LL+kslpMvTYZqUUMJ2LhF/HLaXhVtMWsTYLSDx+gHu1+wbtAOtUDHlxzcaAEMhA2
dix0WqiNr6qAdCkmdWMBTu5vrSJigVW1KdcNElY+e+6ZeUQTK6L2Vt0t+cGVGkM4
K5PdHcGLR1BiAf3k4BguHE4TGGnqN9dF5Rn9nPP6C7QihWzGn15efD2dAXn3Kbho
dMIRgyYiO7uXPm2LrIjtldYb8tPus+V9SWT4hcgnJZrtd9atkqZrJ3dhQf9ZetGs
UwTCzHJ169NNbVyrjCbcy4Uht8Na+t/94Im9hI8n0QKBgQDO6tYnwh1hPg3E+4DY
xCiDAp7v3afJIvC9a1sBtif8KkzZTYH31ww+PRcfDPQUlk/MIDie0u6xIawnBYkC
oN1u9erojcvQbBP0GFylP5hNxYZbI7gPA/7AiGRxyezZPOiVMwdd5fCM7Wv4kucr
c1JCcvtPoDQcFFZOfI+wqqdWnQKBgQDt745Pvckt7/XL7wbfv4BV+cwpLNjc4/3k
ajOLtasgpT8mc0gUH2ejHhpkuhjSUpSTrlFB8EN1kAwmBYy0GOoO9967hm6twmqk
Q5L3OHJ96pYkf1rbyXNE1N7inh5Z3M1H5ONIaliAYLHXOzKsZvI5eUdKAJdSqFLo
uvVCwr4PzQKBgG6W3rzDJ9a4Rr24OgYg2RIkTXQgALQko4xpm2tPwxEoPoiJv2QK
ILYHCpuC3dU+/Qk5U2m3jPFI8OyuLask9RSABPwkBQGxMfztJF8BnVI7tvJxJceI
uBiJDT4v0RHOVvSfIFnUMnvvzRw+z6TObvGq6JyHIDK9v98U/etLWkKVAoGAIIxF
lmjqzUrm/8ep1A+5OYmbQQKug8D4aTeR54mpaCTSt6rLcF0/axPiHmdKn/LF+lG9
MdzxDXLwBn952OUTl4qWwGZKW6Cdv+yyfPkOyGS/tyxovGoZR5ArESr6Eebfefc4
lB5gDuerTDr/2o+WkQAjHV9pU9hMxyNUC5biMv0CgYEAiDlw8lBf3cQs6FxNXs9t
whWpfL0yY7WAONvhfFB0Dpsz52gGDCYRvJekGRz6jOlKDuXJ+Mm1AX4BaufMETI5
QseZxtVPIn+BXm0A1x8w/DifmE1JqQZmPCQPOh3eLx5nSn9LKGIbMgd17mfH3HhU
8WX2mzWjmRA3C/CzdGfCKSk=
-----END PRIVATE KEY-----
我正在从pem文件“crypt_pkcs8.pem”中读取此密钥,但从gRPC调用中以字节数组的形式接收公钥

以下是我的Java代码:

public class Encryption{
public static void main(String args){
    ByteString publicKey = client.getPublicKey(nonce).getRSAEncryptionKey();

    String strKeyPEM = "";
    BufferedReader br = new BufferedReader(new FileReader("crypt_pkcs8.pem"));
    String line;
    while ((line = br.readLine()) != null) {
        strKeyPEM += line+"\n";
    }
    br.close();
    byte[] pt;
    try {
        pt = "h".getBytes("UTF-8");
        byte[] ct =encrypt(publicKey, pt);
        byte[] response= decrypt(strKeyPEM, ct);

        assertEquals(pt, response);
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public static byte[] encrypt(ByteString rawKey ,byte[] message){
    String strippedKey=stripKey(rawKey.toStringUtf8());

    byte[] keyBytes = Base64.getDecoder().decode(strippedKey);
    System.out.println(keyBytes.length);

    Cipher cipher_RSA;
    try {
        cipher_RSA = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        PublicKey pk = keyFactory.generatePublic(spec);
        System.out.println(pk.getAlgorithm()+" format : "+pk.getFormat());

        cipher_RSA.init(Cipher.ENCRYPT_MODE, pk); 
        return cipher_RSA.doFinal(message);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException |
            BadPaddingException | InvalidKeyException | InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }

}

public static byte[] decrypt(String rawKey ,byte[] message){
    String strippedKey=stripPrivateKey(rawKey);

    byte[] keyBytes = Base64.getDecoder().decode(strippedKey);
    System.out.println(keyBytes.length);

    Cipher cipher_RSA;
    try {
        cipher_RSA = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        PrivateKey pk = keyFactory.generatePrivate(spec);
        System.out.println(pk.getAlgorithm()+" format : "+pk.getFormat());

        cipher_RSA.init(Cipher.DECRYPT_MODE, pk); 
        return cipher_RSA.doFinal(message);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException |
            BadPaddingException | InvalidKeyException | InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }
}
public static String stripKey(String key){
    key = key.replace("-----BEGIN RSA PUBLIC KEY-----\n", "");
    key = key.replace("-----END RSA PUBLIC KEY-----", "");
    key = key.replace("\n", "");
    return key;
}

public static String stripPrivateKey(String key){
    key = key.replace("-----BEGIN PRIVATE KEY-----", "");
    key = key.replace("-----END PRIVATE KEY-----", "");
    key = key.replace("\n", "");
    return key;
}


}
我找不到我的actaul代码有任何明显的错误,所以我相信这与钥匙不匹配有关

我还注意到页眉/页脚在公钥和私钥上是不同的。从网上看,这是因为公钥是PKCS#8格式的

我是否也需要将公钥更改为pkcs#8格式?如果是这样,最简单的方法是什么


我还被告知,我应该能够从上面给出的私钥中提取公钥(pkcs8格式)。这很容易做到吗?

如果您可以获得有效的公钥,那么该密钥不是PKCS#8格式,它将是Java期望的X.509(SubjectPublicKeyInfo)格式但是,您的公钥和私钥确实不匹配。您可以使用答案从私钥文件创建正确的公钥文件


Java不直接包含从
RSAPrivateKey
检索公共指数的代码,而不包含CRT参数。但是,如果您想要一个纯Java的解决方案,您可以将
PrivateKey
甚至进一步转换为
RSAPrivateCrtKey
,它确实包含一个检索公共指数的方法。然后,您可以使用RSA
KeyFactory
生成公钥



您还可以使用Bouncy Castle API解析PEM文件以检索Java中的公钥。但是,如果你这样做了,你会有一个陡峭的学习曲线。

别忘了向詹姆斯投赞成票!您的公钥不是pkcs8格式。它是pkcs1格式的。使用openssl将其转换为pkcs8。