![](/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.