gpt4 book ai didi

java - 如何解码 AES-256/CBC/ZeroBytePadding 加密对象

转载 作者:行者123 更新时间:2023-12-02 03:37:32 25 4
gpt4 key购买 nike

我对 Java 加密很陌生。我提供了以下 PHP 代码来解密 AES-256/CBC/ZeroBytePadding 加密对象。

function decrypt($key, $data)
{
if (!in_array(strlen($key), array(32, 48, 64)))
{
throw new Exception("Invalid key");
}

$key_hex = pack('H*', $key);

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);

$ciphertext = base64_decode($data);

# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$iv_dec = substr($ciphertext, 0, $iv_size);

# retrieves the cipher text (everything except the $iv_size in the front)
$ciphertext_dec = substr($ciphertext, $iv_size);

# may remove 00h valued characters from end of plain text
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key_hex, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);

return $result;
}

我需要在java中做同样的事情。经过大量搜索,我编写了以下代码:

 public String decrypt(byte key[], String encrypted)
throws GeneralSecurityException {
if (key.length != 32 || key.length != 48 || key.length != 64) {
throw new IllegalArgumentException("Invalid key size.");
}
byte[] ciphertextBytes = Base64.decodeBase64(encrypted.getBytes());

// Need to find the IV length here. I am using 16 here

IvParameterSpec iv = new IvParameterSpec(ciphertextBytes, 0, 16);
ciphertextBytes = Arrays.copyOfRange(ciphertextBytes, 16,
ciphertextBytes.length);

SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(ciphertextBytes);

// remove zero bytes at the end
int lastLength = original.length;
for (int i = original.length - 1; i > original.length - 16; i--) {
if (original[i] == (byte) 0) {
lastLength--;
} else {
break;
}
}

return new String(original, 0, lastLength);
}

但我需要在这里找到 IV 长度。在 PHP 中,他们使用以下方法来做到这一点: $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);在java中如何实现呢?有人可以帮我吗?

我正在这样调用该方法:

public static void main(String args[]) {
String key = "F5D4471791B79B6360C1EFF4A76250C1D7E5C23F5E4C3C43893B6CCAA796E307";
String encrypted = "F4N8SvpF1zgyMnQKwLlX\\/Dfgsj4kU58pg3kaSrt+AJt9D7\\/3vAfngegtytAdCUwwkQ2nxj8PVABRy0aaeBfsJN9n2Ltco6oPjdcmx8eOI";

try {
String decrypted = decrypt(Hex.decodeHex(key.toCharArray()), encrypted);
System.out.println(decrypted);
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

最佳答案

CBC 模式下的 AES (Rijndael-128) IV 始终与 block 大小相同,即 16 字节或 128 位。如果您继续使用 CBC 模式,则可以对该值进行硬编码或使用 Cipher#getBlockSize()

如果您想使用 AES-256,则需要为您的 JRE/JDK 安装 Unlimited Strength 策略文件 ( Link for Java 8 )。 AES-128 无需修改即可使用,但美国导出限制要求您自行启用更高的 key 大小。

关于java - 如何解码 AES-256/CBC/ZeroBytePadding 加密对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37253622/

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