javax.crypto.BadPaddingException:解密错误

时间:2017-06-18 02:16:31

标签: java encryption cryptography

我已成功使用私钥和公钥进行加密和解密,但是当我尝试使用RSAPrivateCrtKey而不是RSAPrivateKey应用RSA解密时,我遇到此错误。

错误是:

javax.crypto.BadPaddingException: Decryption error
----------------DECRYPTION COMPLETED------------
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at lab6.RSACRT.rsaDecrypt(RSACRT.java:132)
    at lab6.RSACRT.main(RSACRT.java:63)

代码如下所述。提前谢谢!。

    private byte[] rsaDecrypt(RSAPrivateCrtKey rsaprivateCrtKey, byte[] ciphertext) throws IOException {
            System.out.println("\n----------------DECRYPTION STARTED------------");
            byte[] descryptedData = null;
            int cipher1= ciphertext.length;
            System.out.println(cipher1);
            try {
                RSAPrivateCrtKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE);
                Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                descryptedData = cipher.doFinal(ciphertext);
                System.out.println("Decrypted Data: " + new String(descryptedData));

            } catch (Exception e) {
                e.printStackTrace();
            }   

            System.out.println("----------------DECRYPTION COMPLETED------------");
            return descryptedData;      
        }



            public RSAPrivateCrtKey readPrivateKeyFromFile(String fileName) throws IOException{
                FileInputStream fis = null;
                ObjectInputStream ois = null;
                try {
                    fis = new FileInputStream(new File(fileName));
                    ois = new ObjectInputStream(fis);

                    BigInteger modulus = (BigInteger) ois.readObject();
                    BigInteger exponent = (BigInteger) ois.readObject();

                    //Get Private Key
                    RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(modulus, exponent, exponent, exponent, exponent, exponent, exponent, exponent);
                    KeyFactory fact = KeyFactory.getInstance("RSA");
                    RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateCrtKeySpec);

                    return (RSAPrivateCrtKey) privateKey;

                } catch (Exception e) {
                    e.printStackTrace();
                }
                finally{
                    if(ois != null){
                        ois.close();
                        if(fis != null){
                            fis.close();
                        }
                    }
                }
                return null;
            }
        }

1 个答案:

答案 0 :(得分:1)

正如Artjom已经提到的,你对RSAPrivateCrtKeySpec的构造函数的调用是错误的。你似乎需要的只是一个普通的RSAPrivateKeySpec而没有根据中国剩余定理(CRT)执行计算所需的参数。

你现在拥有的是:

//Get Private Key
RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(modulus, exponent, exponent, exponent, exponent, exponent, exponent, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateCrtKeySpec);

return (RSAPrivateCrtKey) privateKey;

而你需要的是:

//Get Private Key
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateKeySpec);

return (RSAPrivateKey) privateKey;

然后你还需要将方法的返回类型更改为RSAPrivateKey

或者,如果有更多对象代表CRT参数,则可能需要更多变量和更多(BigInteger) ois.readObject()调用。

RSA CRT比普通RSA快4倍(并且具有不同的时序攻击特性,但我认为这是一个更高级的主题)。