Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“线程中的异常”;“主要”;javax.crypto.BadPaddingException:Java中的解密错误_Java_Encryption_Rsa_Public Key Encryption - Fatal编程技术网

“线程中的异常”;“主要”;javax.crypto.BadPaddingException:Java中的解密错误

“线程中的异常”;“主要”;javax.crypto.BadPaddingException:Java中的解密错误,java,encryption,rsa,public-key-encryption,Java,Encryption,Rsa,Public Key Encryption,我们正在用Java进行RSA加密/解密 我们能够执行加密,但解密时出错 下面是我们正在使用的代码片段 public class RSA_Read_Write_Key { static String plainText = "This RSA Crypto Java Code"; public static void main(String[] args) throws Exception { byte[] cipherTex

我们正在用Java进行RSA加密/解密

我们能够执行加密,但解密时出错

下面是我们正在使用的代码片段

public class RSA_Read_Write_Key {
    
    static String plainText = "This RSA Crypto Java Code";
    
    public static void main(String[] args) throws Exception {
        byte[] cipherTextArray = encrypt(plainText, "D:\\TCE\\public.key");
        String encryptedText = Base64.getEncoder().encodeToString(cipherTextArray);
        System.out.println("Encrypted Text : " + encryptedText);
        String decryptedText = decrypt(cipherTextArray, "D:\\TCE\\private.key");
        System.out.println("DeCrypted Text : " + decryptedText);    
    }

    public static Key readKeyFromFile(String keyFileName) throws IOException {
        Key key = null;
        InputStream inputStream = new FileInputStream(keyFileName);
        ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(inputStream));
        try {
            BigInteger modulus = (BigInteger) objectInputStream.readObject();
            BigInteger exponent = (BigInteger) objectInputStream.readObject();
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            if (keyFileName.startsWith("public"))
                key = keyFactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
            else
                key = keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, exponent));        
        } 
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            objectInputStream.close();        
        }
        return key;    
    }
    
    public static byte[] encrypt(String plainText, String fileName) throws Exception {
        Key publicKey = readKeyFromFile("D:\\TCE\\public.key");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        return cipherText;   
    }

    public static String decrypt(byte[] cipherTextArray, String fileName) throws Exception {
        Key privateKey = readKeyFromFile("D:\\TCE\\private.key");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte [] plain = new byte[100];
        byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);
        return new String(decryptedTextArray);    
    } 
}
当我们运行代码时,会发现以下错误。有人能帮忙解决这个问题吗?

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
at sun.security.rsa.RSAPadding.unpad(Unknown Source)
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:2164)
at RSAcrypto.RsaToy.decrypt(RsaToy.java:108)
at RSAcrypto.RsaToy.main(RsaToy.java:34)

我发现了以下问题:

  • readKeyFromFile()
    中,检查传递的文件路径是否以
    public
    开头。如果是,则生成公钥。这仅在路径仅包含文件名时有效,通常情况下并非如此,例如在当前代码中使用路径
    D:\\TCE\\public.key
    。要解决此问题,最好应用
    新文件(keyFileName).getName().startsWith(“public”)
    而不是
    keyFileName.startsWith(“public”)

  • encrypt()
    decrypt()
    中传递的文件路径
    fileName
    应转发到
    readKeyFromFile()
    。而是传递硬编码路径
    D:\\TCE\\public.key
    。这可能仅出于测试目的而更改

通过这些更改,只要密钥以适当的格式使用,代码就可以在我的机器上工作。这不是像PKCS#8、PKCS#1或X.508这样的典型格式之一,而是(as
biginger
)序列化的模数和指数(公共或私有,取决于密钥类型),因此可以使用。以这种格式存储键的一种方法是使用序列化模数和指数(如
biginger


还请注意,在某些地方,编码(例如)和解码(例如)是在不指定字符集的情况下完成的,因此使用(依赖于环境的)默认字符集(如果在不同的环境中执行加密和解密,可能会导致问题)。

我发现了以下问题:

  • readKeyFromFile()
    中,检查传递的文件路径是否以
    public
    开头。如果是,则生成公钥。这仅在路径仅包含文件名时有效,通常情况下并非如此,例如在当前代码中使用路径
    D:\\TCE\\public.key
    。要解决此问题,最好应用
    新文件(keyFileName).getName().startsWith(“public”)
    而不是
    keyFileName.startsWith(“public”)

  • encrypt()
    decrypt()
    中传递的文件路径
    fileName
    应转发到
    readKeyFromFile()
    。而是传递硬编码路径
    D:\\TCE\\public.key
    。这可能仅出于测试目的而更改

通过这些更改,只要密钥以适当的格式使用,代码就可以在我的机器上工作。这不是像PKCS#8、PKCS#1或X.508这样的典型格式之一,而是(as
biginger
)序列化的模数和指数(公共或私有,取决于密钥类型),因此可以使用。以这种格式存储键的一种方法是使用序列化模数和指数(如
biginger


还请注意,在某些地方,编码(例如)和解码(例如)是在不指定字符集的情况下完成的,因此使用了(依赖于环境的)默认字符集(如果在不同的环境中执行加密和解密,这可能会导致问题)。

?为什么不使用
密钥库
?这是非常不安全的。@Lorne侯爵:有时有客户请求,他们提供的公钥是这种(不寻常的)格式。关于保存私钥,我完全同意以这种方式保存密钥是不安全的?为什么不使用
密钥库
?这是非常不安全的。@Lorne侯爵:有时有客户请求,他们提供的公钥是这种(不寻常的)格式。关于保存私钥,我完全同意以这种方式保存密钥是不安全的。