用 CryptoJS 解密 Java AES/CBC/PKCS5Padding
Decrypt Java AES/CBC/PKCS5Padding with CryptoJS
我在使用 Java 加密的 CryptoJS 解密文本时遇到一些问题。解密应该用 AES/CBC/PKCS5Padding 完成。加密的字符串是 base64 编码的,我在尝试解密字符串之前对其进行了解码。
这是 Java 代码的样子:
private static byte[] doAES(int mode, byte[] dataToEncrypt, String secretKey, String salt) throws Exception {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, secretKeySpec, ivspec);
return cipher.doFinal(dataToEncrypt);
}
这就是我尝试在 CryptoJS 中解密它的方式。 SharedSecretKey既是secretKey又是Java.
中的salt值
let decoded = Buffer.from(encodedString, 'base64')
console.log("Result: " + CryptoJS.AES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(decoded.toString().substring(32))
}, CryptoJS.enc.Hex.parse(CryptoJS.SHA1(sharedSecretKey).toString().substring(0,32)),
{
iv: CryptoJS.lib.WordArray.create(Buffer.alloc(16)),
}).toString(CryptoJS.enc.Utf8))
其中 decoded 是我要解密的解码 Base64 字符串。但是,这不起作用,我收到错误 'Error: Malformed UTF-8 data'。我不确定是否遗漏了什么,非常感谢您的帮助。
在 CryptoJS 代码中,缺少使用 PBKDF2 派生的密钥。 CryptoJS 默认使用 SHA1。
密文可以通过Base64编码后隐式转换成一个CipherParams
对象:
var encodedString = "0O15lUg8sE1G0+BjO5N2j8AjVKXV4J+18z5DinbM6tYjoILhL0WDTFWbcTiN+pG/";
var key = CryptoJS.PBKDF2(
"my passphrase",
"my salt",
{
keySize: 256 / 32,
iterations: 65536
}
);
var decryptedData = CryptoJS.AES.decrypt(encodedString, key,
{
iv: CryptoJS.enc.Utf8.parse("[=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=]"),
}
);
console.log("Result: " + decryptedData.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
上面示例中的密文是先前使用发布的 Java 代码生成的。
请注意,静态 IV 是不安全的。 IV 通常是为每次加密随机生成的,并与密文一起传递(通常是串联的)。与盐类似,它是为每次密钥推导随机生成的,并与密文和 IV 一起传递,例如盐|iv|密文。 IV 和 salt 都不是秘密,不需要加密。
另外,编码getBytes()
,解码new String()
时,需要在Java代码中指定编码方式,否则可能会出现跨平台问题。
我在使用 Java 加密的 CryptoJS 解密文本时遇到一些问题。解密应该用 AES/CBC/PKCS5Padding 完成。加密的字符串是 base64 编码的,我在尝试解密字符串之前对其进行了解码。
这是 Java 代码的样子:
private static byte[] doAES(int mode, byte[] dataToEncrypt, String secretKey, String salt) throws Exception {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, secretKeySpec, ivspec);
return cipher.doFinal(dataToEncrypt);
}
这就是我尝试在 CryptoJS 中解密它的方式。 SharedSecretKey既是secretKey又是Java.
中的salt值let decoded = Buffer.from(encodedString, 'base64')
console.log("Result: " + CryptoJS.AES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(decoded.toString().substring(32))
}, CryptoJS.enc.Hex.parse(CryptoJS.SHA1(sharedSecretKey).toString().substring(0,32)),
{
iv: CryptoJS.lib.WordArray.create(Buffer.alloc(16)),
}).toString(CryptoJS.enc.Utf8))
其中 decoded 是我要解密的解码 Base64 字符串。但是,这不起作用,我收到错误 'Error: Malformed UTF-8 data'。我不确定是否遗漏了什么,非常感谢您的帮助。
在 CryptoJS 代码中,缺少使用 PBKDF2 派生的密钥。 CryptoJS 默认使用 SHA1。
密文可以通过Base64编码后隐式转换成一个CipherParams
对象:
var encodedString = "0O15lUg8sE1G0+BjO5N2j8AjVKXV4J+18z5DinbM6tYjoILhL0WDTFWbcTiN+pG/";
var key = CryptoJS.PBKDF2(
"my passphrase",
"my salt",
{
keySize: 256 / 32,
iterations: 65536
}
);
var decryptedData = CryptoJS.AES.decrypt(encodedString, key,
{
iv: CryptoJS.enc.Utf8.parse("[=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=]"),
}
);
console.log("Result: " + decryptedData.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
上面示例中的密文是先前使用发布的 Java 代码生成的。
请注意,静态 IV 是不安全的。 IV 通常是为每次加密随机生成的,并与密文一起传递(通常是串联的)。与盐类似,它是为每次密钥推导随机生成的,并与密文和 IV 一起传递,例如盐|iv|密文。 IV 和 salt 都不是秘密,不需要加密。
另外,编码getBytes()
,解码new String()
时,需要在Java代码中指定编码方式,否则可能会出现跨平台问题。