Java 如何解码AES-256/CBC/ZeroBytep添加加密对象
我对Java加密技术相当陌生。我提供了以下PHP代码来解密AES-256/CBC/Zerobytep加密对象Java 如何解码AES-256/CBC/ZeroBytep添加加密对象,java,php,encryption,aes,initialization-vector,Java,Php,Encryption,Aes,Initialization Vector,我对Java加密技术相当陌生。我提供了以下PHP代码来解密AES-256/CBC/Zerobytep加密对象 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
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);
}
但我需要在这里找到静脉长度。在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的IV(Rijndael-128)始终与块大小相同,即16字节或128位。如果继续使用CBC模式,则可以硬编码该值或使用Cipher\getBlockSize()
如果要使用AES-256,则需要为JRE/JDK()安装无限强度策略文件。AES-128无需修改即可使用,但美国出口限制要求您自己启用更高的密钥大小。CBC模式下的AES IV(Rijndael-128)始终与块大小相同,即16字节或128位。如果继续使用CBC模式,则可以硬编码该值或使用Cipher\getBlockSize()
如果要使用AES-256,则需要为JRE/JDK()安装无限强度策略文件。AES-128无需修改即可使用,但美国的出口限制要求您自己启用更高的密钥大小。回答:在Artjom B的帮助下。我创建了将解密AES-256/CBC/Zerobytep加密字符串的代码。我为其他需要帮助的人发布这篇文章 1。首先,您必须下载JDK版本的Java加密扩展(JCE)无限强度管辖权策略 2.提取zip文件,并将本地_policy.jar和US_export_policy.jar放在路径/JDK path/jre/lib/security中。这是必需的,因为我的密钥是64字节。AES需要16/24/32字节的密钥 3.复制粘贴我的代码并根据您的要求进行更改:p
import java.security.GeneralSecurityException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.binary.Base64;
public class Decryption {
public static void main(String args[]) {
//I have changed the original key. So mere copy pasting may not work. Put your key here.
String key = "FfDaaaaaaa444aaaa7aaEFF4A76efaaaaaE5C23F5E4C3adeaaaaaaCAA796E307";
String encrypted = "8AQ8SvpF1zgyNyxKwLlX\\/cGzwLE5skU58pg3kaSrt+AJt9D7\\/3vaNRPZISIKMdCUwwkQ2nxj8PVABRy0aaeBfsJN9n2Ltco6oPjdcmx8eOI";
String decrypted = "";
try {
try {
decrypted = decrypt(Hex.decodeHex(key.toCharArray()), encrypted);
} catch (DecoderException e) {
e.printStackTrace();
}
System.out.println(decrypted);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
public static 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());
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);
}
}
感谢@Artjom B。感谢您的帮助和专业知识:)。回答:在Artjom B的帮助下。我已经创建了将解密AES-256/CBC/ZeroBytep加密字符串的代码。我为其他需要帮助的人发布这篇文章 1。首先,您必须下载JDK版本的Java加密扩展(JCE)无限强度管辖权策略 2.提取zip文件,并将本地_policy.jar和US_export_policy.jar放在路径/JDK path/jre/lib/security中。这是必需的,因为我的密钥是64字节。AES需要16/24/32字节的密钥 3.复制粘贴我的代码并根据您的要求进行更改:p
import java.security.GeneralSecurityException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.binary.Base64;
public class Decryption {
public static void main(String args[]) {
//I have changed the original key. So mere copy pasting may not work. Put your key here.
String key = "FfDaaaaaaa444aaaa7aaEFF4A76efaaaaaE5C23F5E4C3adeaaaaaaCAA796E307";
String encrypted = "8AQ8SvpF1zgyNyxKwLlX\\/cGzwLE5skU58pg3kaSrt+AJt9D7\\/3vaNRPZISIKMdCUwwkQ2nxj8PVABRy0aaeBfsJN9n2Ltco6oPjdcmx8eOI";
String decrypted = "";
try {
try {
decrypted = decrypt(Hex.decodeHex(key.toCharArray()), encrypted);
} catch (DecoderException e) {
e.printStackTrace();
}
System.out.println(decrypted);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
public static 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());
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);
}
}
感谢@Artjom B。感谢您的帮助和专业知识:)。感谢您的帮助。现在,它给出了一个错误:无效的AES密钥长度:64字节我已经添加了代码。现在你能帮我吗?我相信string.getByte()是所有问题的根源。AES仅适用于16、24和32字节的键。似乎您有一个64个字符的密钥,如果假定为十六进制编码,则为32字节。如果在PHP中使用相同的键字符串,则只需使用前32个字符。如果要将实际密钥转换为十六进制,则需要将其转换回Java。如果要在PHP代码中使用AES-256,则需要为特定的Java版本安装无限强度策略文件。在将密钥解码为字节之前执行大小检查,而在Java中则在该事实发生之后执行。因此,您应该与16、24或32字节(即128、192、256字节)进行比较。当然,您也可以等到
SecretKeySpec
或Cipher
抛出异常。谢谢您的帮助。现在,它给出了一个错误:无效的AES密钥长度:64字节我已经添加了代码。现在你能帮我吗?我相信string.getByte()是所有问题的根源。AES仅适用于16、24和32字节的键。似乎您有一个64个字符的密钥,如果假定为十六进制编码,则为32字节。如果在PHP中使用相同的键字符串,则只需使用前32个字符。如果要将实际密钥转换为十六进制,则需要将其转换回Java。如果要在PHP代码中使用AES-256,则需要为特定的Java版本安装无限强度策略文件。在将密钥解码为字节之前执行大小检查,而在Java中则在该事实发生之后执行。因此,您应该与16、24或32字节(即128、192、256字节)进行比较。当然,您也可以等到SecretKeySpec
或Cipher
抛出异常。请不要编辑问题以包含答案。你可以发布自己问题的答案。完成此操作后,请将问题回滚到第4版。问题中的答案使用的密钥不是有效的十六进制编码,因为它包含0-9、a-f、a-f以外的字符。此代码应引发错误。请不要编辑问题以包含答案。你可以发布自己问题的答案。完成此操作后,请将问题回滚到修订版4。问题中的答案使用的密钥不是有效的十六进制编码,因为它包含0-9、a-f、a-f以外的字符。此代码应引发错误。