javax.crypto.BadPaddingException AES 加密时出错
javax.crypto.BadPaddingException error during AES encryption
我需要使用 AES 加密和解密文本。我可以在本地调用这两种方法并且它有效,但是当我 运行 它在 class 之外时,我得到 javax.crypto.BadPaddingException 错误。我想我在某处丢失了数据,但你找不到哪里。
这是代码:
public class AES {
public String encryptAES(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public String decryptAES(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
private byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
return result;
}
private String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
String HEX = "0123456789ABCDEF";
for (int i = 0; i < buf.length; i++) {
result.append(HEX.charAt((buf[i] >> 4) & 0x0f)).append(HEX.charAt(buf[i] & 0x0f));
}
return result.toString();
}
错误指向
byte[] decrypted = cipher.doFinal(encrypted);
我看到有几处需要修复..
首先 SecureRandom
的种子不会产生相同的输出。因此,如果您尝试通过指定相同的种子来创建相同的密钥,它将不起作用。
其次 ..你应该确保用相同的属性实例化你的加密和解密密码..目前你没有。
也,当您指定CBC模式时,您需要处理初始化向量。如果你没有在加密上指定一个,密码会为你生成一个。这个你需要在解密时获取并提供。
解决这些问题并不一定能解决所有问题,但应该会引导您朝着正确的方向前进。查看右侧的一些相关问题。Whosebug 有大量可用的 AES 示例。
我需要使用 AES 加密和解密文本。我可以在本地调用这两种方法并且它有效,但是当我 运行 它在 class 之外时,我得到 javax.crypto.BadPaddingException 错误。我想我在某处丢失了数据,但你找不到哪里。 这是代码:
public class AES {
public String encryptAES(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public String decryptAES(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
private byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
return result;
}
private String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
String HEX = "0123456789ABCDEF";
for (int i = 0; i < buf.length; i++) {
result.append(HEX.charAt((buf[i] >> 4) & 0x0f)).append(HEX.charAt(buf[i] & 0x0f));
}
return result.toString();
}
错误指向
byte[] decrypted = cipher.doFinal(encrypted);
我看到有几处需要修复..
首先 SecureRandom
的种子不会产生相同的输出。因此,如果您尝试通过指定相同的种子来创建相同的密钥,它将不起作用。
其次 ..你应该确保用相同的属性实例化你的加密和解密密码..目前你没有。
也,当您指定CBC模式时,您需要处理初始化向量。如果你没有在加密上指定一个,密码会为你生成一个。这个你需要在解密时获取并提供。
解决这些问题并不一定能解决所有问题,但应该会引导您朝着正确的方向前进。查看右侧的一些相关问题。Whosebug 有大量可用的 AES 示例。