簡體   English   中英

線程“main”中的異常 javax.crypto.BadPaddingException:Java 中的解密錯誤

[英]Exception in thread “main” javax.crypto.BadPaddingException: Decryption error in Java

我們致力於用 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 為了解決這個問題,最好應用new File(keyFileName).getName().startsWith("public")而不是keyFileName.startsWith("public")

  • encrypt()decrypt()傳遞的文件路徑fileName應該轉發到readKeyFromFile() 相反,硬編碼路徑D:\\\\TCE\\\\public.key被傳遞。 這可能已更改僅用於測試目的。

通過這些更改,只要以適當的格式使用密鑰,代碼就可以在我的機器上運行。 這不是像 PKCS#8、PKCS#1 或 X.508 這樣的典型格式之一,而是(如BigInteger )序列化的模數和指數(公共或私有取決於密鑰類型),因此兩者都可以用ObjectInputStream讀取. 以這種格式存儲密鑰的一種方法是使用ObjectOutputStream序列化模數和指數(如BigInteger )。

另請注意,在某些地方編碼(例如plainText.getBytes() )和解碼(例如new String(decryptedTextArray) plainText.getBytes() new String(decryptedTextArray) )是在沒有指定字符集的情況下完成的,因此使用(依賴於環境的)默認字符集(這可能導致如果加密和解密在不同的環境中執行會出現問題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM