pal*_*laa 19 java encryption cryptography exception
我正在研究AES算法,我有这个例外,我无法解决.
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
Run Code Online (Sandbox Code Playgroud)
异常发生在解密部分.我在与解密算法不同的地方初始化密钥
KeyGenerator kgen = KeyGenerator.getInstance("AES");//key generation for AES
kgen.init(128); // 192 and 256 bits may not be available
Run Code Online (Sandbox Code Playgroud)
然后我用我从文件中读取的密文传递给下面的方法
public String decrypt(String message, SecretKey skey) {
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher;
byte[] original = null;
try {
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Original string: "
+ message);
original = cipher.doFinal(message.trim().getBytes()); //here where I got the exception
String originalString = new String(original);
}
//catches
Run Code Online (Sandbox Code Playgroud)
编辑 这里是加密方法.
public String encrypt(String message, SecretKey skey) {
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher;
byte[] encrypted = null;
try {
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(message.getBytes());
System.out.println("raw is " + encrypted);
} catches
return asHex(encrypted);
}
Run Code Online (Sandbox Code Playgroud)
这是asHex方法
public static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
Run Code Online (Sandbox Code Playgroud)
这是我从文件中读取密文的地方
static public String readFile(String filePath) {
StringBuilder file = new StringBuilder();
String line = null;
try {
FileReader reader = new FileReader(filePath);
BufferedReader br = new BufferedReader(reader);
if (br != null) {
line = br.readLine();
while (line != null) {
file.append(line);
// System.out.println("line is " + line);
line = br.readLine();
}
}
br.close();
reader.close();
} catch (IOException ex) {
Logger.getLogger(FileManagement.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("line is " + file.toString());
return String.valueOf(file);
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮忙吗?
dog*_*ane 14
好吧,问题是您正在将加密的字节转换为十六进制字符串(使用该asHex
方法),但是没有正确地将十六进制字符串转换回字节数组以进行解密.你不能使用getBytes
.
您可以使用以下方法将十六进制字符串转换为字节数组:
public static byte[] fromHexString(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
Run Code Online (Sandbox Code Playgroud)
然后更改您的解密方法以使用:
original = cipher.doFinal(fromHexString(message));
Run Code Online (Sandbox Code Playgroud)
小智 5
我确实有一个错误的填充异常,并且无法在互联网上找到解决我的问题的方法。由于我是经过一段时间的努力才找到的,所以我把它放在这里。
我的问题是,我正在读取硬盘驱动器上的文件,并通过缓冲区对其进行加密,始终调用 doFinal() 方法而不是 update() 方法。所以在解密时,我有填充错误
input = new FileInputStream(file);
output = new FileOutputStream(newFile);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, mySecretKey);
byte[] buf = new byte[1024];
count = input.read(buf);
while (count >= 0) {
output.write(cipher.update(buf, 0, count)); // HERE I WAS DOING doFinal() method
count = input.read(buf);
}
output.write(cipher.doFinal()); // AND I DID NOT HAD THIS LINE BEFORE
output.flush();
Run Code Online (Sandbox Code Playgroud)
解密时,使用相同的方法,但使用带有 DECRYPT_MODE 的 Cipher init
input = new FileInputStream(file);
output = new FileOutputStream(newFile);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, mySecretKey);
byte[] buf = new byte[1024];
count = input.read(buf);
while (count >= 0) {
output.write(cipher.update(buf, 0, count)); // HERE I WAS DOING doFinal() method
//AND HERE WAS THE BadPaddingExceotion -- the first pass in the while structure
count = input.read(buf);
}
output.write(cipher.doFinal()); // AND I DID NOT HAD THIS LINE BEFORE
output.flush();
Run Code Online (Sandbox Code Playgroud)
编写代码后,我不再有任何 BadPaddingException。
我可以确切地说,只有当原始清晰文件长度(通过 file.length() 获得)大于缓冲区时才会出现此异常。否则,我们不需要在 while 结构中多次传递,我们可以使用 doFinal() 调用一次加密。这证明了跟随您尝试加密的文件大小的异常的随机字符是合理的。
我希望你有一个很好的阅读!
归档时间: |
|
查看次数: |
81643 次 |
最近记录: |