我搜索了很多,但我还没有找到一个很好的解决方案如何解决这个问题。我有一个应用程序,它必须使用AES 256来解密长的十六进制字符串。用十六进制字符串加密和解密
为了测试它,我创建了一个测试方法,将长文本加密为十六进制,然后将其转换并解密。
如果我运行此方法,我总是得到以下错误:鉴于最终块没有正确填充。我在解密方法中收到此错误。
的测试方法看起来像这样:
@Test
public void testEncAndDecRequestWithHexString() throws UnsupportedEncodingException {
CryptoHelper cryptoHelper = new CryptoHelper("AES256");
String paramStr = "ABCB28BCEE5947B8AECE3386871EC0DF&{D5CA99D2-506B-4864-8971-E87821D6B105}&7523429";
//encrypt the param string
byte[] paramByteEnc = cryptoHelper.encryptBytesToBytes(paramStr.getBytes("ASCII"), PARAM_KEY, PARAM_IV);
//convert it to hex
String encryptedHexStr = cryptoHelper.byteArrayToHexStr(paramByteEnc);
//convert it back to a byte array
byte[] encryptedHexBytes = cryptoHelper.hexStrToByteArray(encryptedHexStr);
// decrypt it
byte[] paramByteDecrypted = cryptoHelper.decryptBytesToBytes(encryptedHexBytes, encryptedHexBytes.length, PARAM_KEY, PARAM_IV);
String decryptedStr = new String(paramByteDecrypted);
assertEquals("ABCB28BCEE5947B8AECE3386871EC0DF&{D5CA99D2-506B-4864-8971-E87821D6B105}&7523429", decryptedStr);
}
的CryptHelper类有下列方法:
@Override
public byte[] encryptBytesToBytes(byte[] plainData, byte[] key, byte[] iv) {
try {
initCipher(Cipher.ENCRYPT_MODE, key, iv);
return aesCipher.doFinal(plainData);
} catch (IllegalBlockSizeException | BadPaddingException e) {
log.severe(e.getMessage());
}
return null;
}
@Override
public byte[] decryptBytesToBytes(byte[] encryptedBytes, int length,
byte[] key, byte[] iv) {
try {
initCipher(Cipher.DECRYPT_MODE, key, iv);
return aesCipher.doFinal(encryptedBytes, 0, length);
} catch (IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
return null;
}
private void initCipher(int mode, byte[] keyBytes, byte[] ivBytes) {
try {
// create shared secret and init cipher mode
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(mode == Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes));
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
e.printStackTrace();
}
}
public String byteArrayToHexStr(byte[] encrypted) {
StringBuilder hex = new StringBuilder();
for (byte b : encrypted) {
hex.append(String.format("%02X", b));
}
return new String(hex.toString());
}
public byte[] hexStrToByteArray(String hex) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.length() - 1; i += 2) {
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
sb.append((char) decimal);
}
String temp = sb.toString();
return temp.getBytes();
}
我用同样的密钥和初始化向量用于解密处理,所以这个问题是不错误的键或初始化向量。我也确信,这里的每个功能都正确地完成了他们的工作。如果您不使用函数hexStrToByteArray()和byteArrayToHexStr(),并只使用加密字节进行解密,则不会出现问题。我认为有一个编码/解码问题,但我不知道如何在Java中处理它。如果我使用getBytes(“UTF-8”)和新的String(byte [],“UTF-8”),我得到一个IllegalBlockSizeException。
我希望你能帮助我发现我是否正确的做法以及做错了什么。
'hexString.append(Integer.toHexString(0xFF的&digestBytes [1]));' 这是怎么了我将该字节转换为十六进制。 – 2014-11-05 16:42:21
不知道其** **问题,但你的'byteArrayToHexStr/hexStrToByteArray'不能正确处理负值。 – 2014-11-05 16:49:16
@DavidSoroko:byteArrayToHexStr看起来正确,另一种方法看起来不正确。 – 2014-11-05 23:35:10