問題描述
我正在做一個簡單的程序來使用 Java 中的 RSA 算法進行加密/解密.我創建一個密碼對象如下:
I am doing a simple program to encrypt/decrypt using RSA algorithm in Java. I create a cipher object as follows:
//Create a Cipher object
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
我通過調用 encrypt 函數進行加密:
I do the encryption by calling the encrypt function:
String cipher=encrypt(textByte, pair, rsaCipher);
System.out.println("The Encryption using RSA Algorithm : "+cipher);
而解密為:
//Decryption
String plain=decrypt(Base64.decodeBase64(cipher),pair, rsaCipher);
System.out.println("The Decryption using RSA Algorithm : "+plain);
當我顯示輸出時,解密輸出在原文前返回一個長空格:
When I display the output, the decryption output returns a long space before the original text:
但是,當我將用于創建 Cipher 對象的代碼編輯為://創建一個密碼對象密碼rsaCipher = Cipher.getInstance("RSA");
However, when I edit the code for creating the Cipher object to be: //Create a Cipher object Cipher rsaCipher = Cipher.getInstance("RSA");
即刪除操作模式和填充參數,問題得到解決,輸出變為:
i.e, removed the operation mode and padding arguments, the problem get resolved and the output becomes:
問題出在哪里.在第一種情況下(出現空格時),我指定了 NoPadding?為什么空格會出現在解密的消息中?即使我使用了填充,我希望這不應該發生.
Where is the problem. In the first case (when the space appears), I specified NoPadding? Why the spaces appears in the decrypted message ? Even if I used padding, I expect this should not happen.
這是加密和解密方法:
public static String encrypt(byte[] textBytes, KeyPair pair, Cipher rsaCipher) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
//get the public key
PublicKey pk=pair.getPublic();
//Initialize the cipher for encryption. Use the public key.
rsaCipher.init(Cipher.ENCRYPT_MODE, pk);
//Perform the encryption using doFinal
byte[] encByte = rsaCipher.doFinal(textBytes);
// converts to base64 for easier display.
byte[] base64Cipher = Base64.encodeBase64(encByte);
return new String(base64Cipher);
}//end encrypt
public static String decrypt(byte[] cipherBytes, KeyPair pair, Cipher rsaCipher) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException
{
//get the public key
PrivateKey pvk=pair.getPrivate();
//Create a Cipher object
//Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
//Initialize the cipher for encryption. Use the public key.
rsaCipher.init(Cipher.DECRYPT_MODE, pvk);
//Perform the encryption using doFinal
byte[] decByte = rsaCipher.doFinal(cipherBytes);
return new String(decByte);
}//end decrypt
推薦答案
你的問題確實出在padding上.安全 RSA 功能需要某種填充,無論是 PKCS#1 1.5 還是實踐中的 OAEP 填充.此外,還需要找到加密明文的開頭和結尾.
Your problem is indeed with the padding. Some kind of padding, either PKCS#1 1.5 or OAEP padding in practice, is required for secure RSA functionality. Furthermore, it is required to find the start and end of the encrypted plain text.
RSA 的模冪運算是使用大整數執行的.然后將這些操作的結果表示為八位字節字符串.這些八位字節字符串基本上是整數的大端、無符號、固定長度表示.這些整數用 00
值字節填充(這在 RSA 標準中稱為 I2OS 原語).所以你看到的是模冪運算的結果,00
填充仍然存在.
The modular exponentiation of RSA is performed using large integers. The results of these operations are then represented as octet strings. These octet strings are basically big endian, unsigned, fixed length representation of an integer. These integers are left padded with 00
valued bytes (this is called the I2OS primitive in the RSA standard). So what you are seeing is the result of the modular exponentiation, with the 00
padding still in place.
長話短說,始終使用填充方案.如今,OAEP 將更可取.與混合加密方案一起使用,或使用更高級別的容器格式,例如 CMS 或 PGP.
Long story short, always use a padding scheme. Nowadays, OAEP would be preferable. Use it together with hybrid encryption scheme, or use a higher level container format such as CMS or PGP.
這篇關于使用 Java 進行 RSA 加密/解密的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!