gpt4 book ai didi

java - 用十六进制字符串加密和解密

转载 作者:行者123 更新时间:2023-11-29 05:15:19 25 4
gpt4 key购买 nike

我搜索了很多,但我还没有找到解决这个问题的好办法。我有一个必须使用 AES 256 解密长十六进制字符串的应用程序。

为了测试它,我创建了一个测试方法,将长文本加密为十六进制,然后将其转换回并解密。

如果我运行此方法,我总是会收到以下错误:未正确填充给定的最终 block 。我在解密方法中收到此错误。

测试方法如下所示:

@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();
}

我在解密过程中使用了相同的 key 和初始化 vector ,所以问题不是错误的 key 或初始化 vector 。我也确信这里的每个功能都在正确地完成他们的工作。如果您不使用函数 hexStrToByteArray() 和 byteArrayToHexStr() 并且仅使用加密字节进行解密,则没有问题。我认为存在编码/解码问题,但我不知道如何在 java 中处理它。如果我使用 getBytes("UTF-8") 和 new String(byte[], "UTF-8") 我会得到一个 IllegalBlockSizeException。

我希望你能帮助我找出我的方法是否正确以及我做错了什么。

最佳答案

这是一个明确的指示,如果库函数已经被定义,您就不应该编写它们。改为使用来自 Bouncy CaSTLe、Guava 或 Apache 编解码器的十六进制编解码器(直到 Oracle 终于看到了曙光并在 java.util 包中提供了一个)。

如果您确实自己实现了它,请不要将字符误认为是字节:

public byte[] hexStrToByteArray(String hex) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(hex.length() / 2);

for (int i = 0; i < hex.length(); i += 2) {
String output = hex.substring(i, i + 2);
int decimal = Integer.parseInt(output, 16);
baos.write(decimal);
}
return baos.toByteArray();
}

关于java - 用十六进制字符串加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26762045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com