使用 Java 进行 RSA 加密/解密
我正在做一个简单的程序来使用 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.
相关文章