首先,我已经审查了论坛上的所有条目,但我仍然无法找到问题的解决方案。 我必须测量用DES编码和解码文本所花费的时间,并与其他算法进行比较。
当我运行代码时,出现此错误: BadPaddingException:pad block corrupted 。当我调试时,代码在此行中失败:
byte [] plaintext = cipher.doFinal(cipherBytes);
我使用类Base64对String< - >进行编码/解码字节[]
有什么想法吗?
感谢
private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
private static int KEY_LENGTH = 64;
public static SecretKey deriveKeyDES() {
try {
long start = System.currentTimeMillis();
KeyGenerator kgen = KeyGenerator.getInstance("DES");
kgen.init(KEY_LENGTH);
SecretKey result = kgen.generateKey();
long elapsed = System.currentTimeMillis() - start;
return result;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public static String encrypt(String plaintext, SecretKey key) {
try {
long start = System.currentTimeMillis();
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8"));
long elapsed = System.currentTimeMillis() - start;
return toBase64(cipherText);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static String toBase64(byte[] bytes) {
return Base64.encodeToString(bytes, Base64.NO_WRAP).trim();
}
public static String decrypt(String ciphertext, SecretKey key) {
try {
byte[] cipherBytes = fromBase64(ciphertext);
long start = System.currentTimeMillis();
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);
// This is where I get exception
byte[] plaintext = cipher.doFinal(cipherBytes);
String plainrStr = new String(plaintext, "UTF-8").trim();
long elapsed = System.currentTimeMillis() - start;
return plainrStr;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static byte[] fromBase64(String base64) {
return Base64.decode(base64, Base64.NO_WRAP);
}
答案 0 :(得分:1)
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);
// byte[] plaintext = cipher.doFinal(cipherBytes);
// ^-- You shouldn't pass cipherBytes twice.
// v-- instead use the parameter-less method:
byte[] plaintext = cipher.doFinal();
答案 1 :(得分:1)
当最后一个密文块不计算为有效的纯文本时,会发生填充异常。如果最后一个密文块被破坏或密钥不正确,就会发生这种情况。对于CBC模式,如果倒数第二个密文被更改(但您使用的是ECB模式加密),也会发生这种情况。
在您的情况下,deriveKeyDES()
始终生成随机密钥。虽然我们没有得到对安全方法的实际调用,但我会推测您使用不同的密钥进行加密和解密。在这种情况下,生成的纯文本很可能不包含有效的填充字节。
Rasmus回答肯定会指出代码中的错误,它会搞砸你的时间并返回纯文本两次,但它不会删除BadPaddingException
。
答案 2 :(得分:0)
我在一个源代码中遇到了同样的问题,而在另一个源代码中遇到了IllegalBlockSizeException。 通过返回编码数据解决了这两个问题,如:
public String encrypt(String input) {
try {
byte[] inputBytes = input.getBytes("UTF-8");
byte[] enc = encryptCipher.doFinal(inputBytes);
// and problem was in return encoding. That's how i fixed it
return Base64.encodeToString(enc,Base64.DEFAULT);
.....
}
}
给你一个解密代码:
public String decrypt(String input) {
try {
byte[] dec = Base64.decode(input.getBytes(), Base64.DEFAULT);
//here had exception
byte[] utf8 = decryptCipher.doFinal(dec);
return new String(utf8,"UTF8");
} catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
我应该提交,它有BadPaddingException和IllegalBlockSizeException 只在解密方法 byte [] utf8 = decryptCipher.doFinal(dec); (你在同一个地方有一个例子: < em> byte [] plaintext = cipher.doFinal(cipherBytes); ),但真正的错误在于加密方法(返回值)
这就是我建议您在加密方法中使用该代码的原因:
return Base64.encodeToString(enc,Base64.DEFAULT);
P.S试图在你的问题上给出完整答案。