![](/img/trans.png)
[英]javax.crypto.BadPaddingException: Message is larger than modulus
[英]Why do I get "BadPaddingException: Message is larger than modulus" when decrypting data stored as a bit array from text file?
我使用 RSA 算法来加密一些数字,然后将这些数字存储在文本文件中的位数组中。 这些数字被加密并添加到文本文件中就好了,但是当我尝试使用下面的方法解密它们时,我在控制台中收到“BadPaddingException:消息大于模数”这个错误。 我对加密很陌生,这真的让我失望。
Cipher cipher;
KeyPair pair;
public byte[] encryptData(String data) throws BadPaddingException, IllegalBlockSizeException {
try{
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
pair = keyPairGen.generateKeyPair();
PublicKey publicKey = pair.getPublic();
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.update(data.getBytes());
cipher.doFinal();
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException ex){
ex.printStackTrace();
}
return cipher.doFinal();
}
将数据写入文件
String nums = request.getParameter("numbers");
String password = (String) session.getAttribute("password");
String filename = (password +".txt");
File dir = new File("/volume");
dir.mkdir();
File myfile = new File(dir, filename);
System.out.println("filename: " + filename);
FileOutputStream output;
try {
if (myfile.isFile()){
output = new FileOutputStream(myfile, true);
}
else{
output = new FileOutputStream(myfile);
}
byte[] encryptednums = encryptData(nums);
output.write(encryptednums);
output.close();
} catch (BadPaddingException | IllegalBlockSizeException | IOException e) {
e.printStackTrace();
}
读取文件
public byte[] bytesFileReader(File filename){
try {
return Files.readAllBytes(Paths.get(String.valueOf(filename)));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
解密
HttpSession session = request.getSession();
KeyPair pair = (KeyPair) session.getAttribute("keypair");
Cipher cipher = (Cipher) session.getAttribute("cipher");
String password = (String) session.getAttribute("password");
String filename = (password +".txt");
File dir = new File("/volume");
dir.mkdir();
File myfile = new File(dir, filename);
byte[] encryptedBytes = bytesFileReader(myfile);
try {
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
byte[] decipheredText = cipher.doFinal(encryptedBytes);
System.out.println(new String(decipheredText, StandardCharsets.UTF_8));
} catch (InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace();
}
}
可能值得注意的是,这一切都发生在两个 java servlet 上。
您的代码中有一个主要问题和一些小问题。 让我们开始一个次要的:当将字符串转换为字节数组时,反之亦然,所有转换都必须使用固定编码(请参阅您的 encryptData 方法):
cipher.update(data.getBytes());
主要问题是进行 RSA 加密时的明文大小限制。 您可以使用此公式计算最大明文大小
1) RSA keysize divided by 8 - e.g. 2048 / 8 = 256 bytes
2) PKCS1 padding takes 11 bytes
3) maximum of plaintext bytes: 256 - 11 = 245 bytes
在我的示例代码中,我使用了大小为 ( UNSECURE ) 512 位 = 64 字节的 RSA 密钥对,减去 11 个字节用于填充,有 53 个字节可以加密。 第一轮将按预期运行,下一个 54 字节数据的加密运行到
IllegalBlockSizeException: Data must not be longer than 53 bytes
由于您的代码只有方法但没有显示写入的数据,我只能假设您尝试在一次运行中解密所有写入的数据 - 失败的可能性很高。
我的代码遇到错误的原因(而不是你的)是更新和双重(!)最终调用(注意我遗漏了你可能需要的捕获):
change:
cipher.update(data.getBytes());
cipher.doFinal();
return cipher.doFinal();
to:
return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
输出:
BadPaddingException: Message is larger than modulus
encrypting 12345678901234567890123456789012345678901234567890123
encryptedData length: 64
decryptedData: 12345678901234567890123456789012345678901234567890123
encrypting 123456789012345678901234567890123456789012345678901234
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 53 bytes
安全警告:此代码使用不安全的 512 位长 RSA 密钥(使用最少 2048 位)并使用易受攻击的 RSA 填充 PKCS1 进行加密 - 请使用 OEAP 填充! .
代码:
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
public class Main {
static KeyPair keyPair;
public static void main(String[] args) throws NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException {
System.out.println("BadPaddingException: Message is larger than modulus");
// https://stackoverflow.com/questions/64722370/why-do-i-get-badpaddingexception-message-is-larger-than-modulus-when-decrypti
keyPair = generateKeyPair(512); // ### do not use RSA keys with 512 bits length, minimum 2048 bits
// 512 bit = 64 byte - 11 byte for padding = maximal 53 bytes data to encrypt
System.out.println("\nencrypting 53 chars");
String data53Chars = "12345678901234567890123456789012345678901234567890123";
//String data53Chars = "12345678901234567890";
System.out.println("encrypting " + data53Chars);
byte[] encryptedData = encryptData(data53Chars);
System.out.println("encryptedData length: " + encryptedData.length);
String decryptedData = decryptData(encryptedData);
System.out.println("decryptedData: " + decryptedData);
// now 54 bytes
System.out.println("\nencrypting 54 chars");
String data54Chars = "123456789012345678901234567890123456789012345678901234";
System.out.println("encrypting " + data54Chars);
encryptedData = encryptData(data54Chars);
System.out.println("encryptedData length: " + encryptedData.length);
decryptedData = decryptData(encryptedData);
System.out.println("decryptedData: " + decryptedData);
}
public static byte[] encryptData(String data) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
PublicKey publicKey = keyPair.getPublic();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
}
public static String decryptData(byte[] encryptedBytes) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException {
byte[] decipheredText = new byte[0];
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
decipheredText = cipher.doFinal(encryptedBytes);
return new String(decipheredText, StandardCharsets.UTF_8);
}
static KeyPair generateKeyPair(int keyLength) throws NoSuchAlgorithmException {
final String KEY_ALGORITHM = "RSA";
KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keygen.initialize(keyLength, new SecureRandom());
KeyPair keyPair = keygen.generateKeyPair();
return keyPair;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.