java 中的 AES 加密和 java 脚本中使用 CryptoJS 的解密
AES encryption in java and decryption in javascript using CryptoJS
我有以下代码使用 AES/CTR/NOPADDING 模式加密 java 中的一些文件内容。我正在使用 javax 的加密包。我也使用相同的密钥生成密钥和 iv.
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
byte[] secretKey = Base64.decodeBase64("uQsaW+WMUrjcsq1HMf+2JQ==");
SecretKeySpec key = new SecretKeySpec(secretKey, "AES");
IvParameterSpec iv = new IvParameterSpec(secretKey);
cipher.init(mode, key , iv);
FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
FileOutputStream fileOutputStream = new FileOutputStream(destFilePath);
int read = 0;
while ((fileInputStream.available()) > 0) {
byte[] block = new byte[4096];
read = fileInputStream.read(block);
byte[] writeBuffer = cipher.update(block);
fileOutputStream.write(writeBuffer, 0, read);
}
byte[] writeBuffer = cipher.doFinal();
fileOutputStream.write(writeBuffer, 0, writeBuffer.length);
fileInputStream.close();
fileOutputStream.close();
我无法使用 cryptojs 解密 java 脚本中的加密内容。
这是我试过的东西。
var key = CryptoJS.enc.Hex.parse(atob('uQsaW+WMUrjcsq1HMf+2JQ=='));
var decrypted = CryptoJS.AES.decrypt(encryptedContent, key, {
mode: CryptoJS.mode.CTR,
iv: key,
padding: CryptoJS.pad.NoPadding
});
var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted);
有人可以告诉我我做错了什么吗?或者告诉我怎么做。
我可以在 java 和 java 脚本中独立加密和解密。
你的加密循环是错误的。我不确定这是否是您问题的原因,但我会从它开始
read = fileInputStream.read(block);
byte[] writeBuffer = cipher.update(block);
即使你只读取块的部分大小,对整个块执行加密操作,你可以尝试
byte[] writeBuffer = cipher.update(block, 0, read);
关于使用密钥作为 IV,我必须强调,使用 CTR 模式,安全性将被完全破坏。
在 CryptoJS
-documentation 中解释了 CryptoJS.decrypt()
方法需要哪些数据类型和参数以及哪些编码器可用:
- 密钥必须作为
WordArray
传递给 CryptoJS.decrypt()
方法。由于密钥数据是 Base64 编码的,因此可以使用 CryptoJS.enc.Base64.parse()
方法将它们转换为 WordArray
。
- 密文可以作为
CipherParams
对象中的 WordArray
传递给 CryptoJS.decrypt()
方法。 Java-代码将加密数据存储在文件中。假设字符串 encryptedContent
包含这些数据作为十六进制字符串(不幸的是,这不会从发布的代码中出现,因此必须在此处进行假设),它们可以转换为 WordArray
CryptoJS.enc.Hex.parse()
-方法并包装在CipherParams
-对象中。
CryptoJS.decrypt()
-方法returns一个WordArray
可以用CryptoJS.enc.Utf8.stringify()
-方法转换成字符串。
如果输入文件中包含以下纯文本:
This is the plain text which needs to be encrypted!
Java代码在输出文件中存储以下字节序列(=加密数据):
52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7
解密的Java脚本代码是:
var key = CryptoJS.enc.Base64.parse('uQsaW+WMUrjcsq1HMf+2JQ==');
var encryptedContent = '52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7';
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Hex.parse(encryptedContent)
});
var decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
mode: CryptoJS.mode.CTR,
iv: key,
padding: CryptoJS.pad.NoPadding
});
var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted);
console.log(decryptedText);
在控制台显示原始纯文本。要 运行 上面的代码至少需要 CryptoJS 版本 3.1.4(参见 versions, cdnjs)。
我有以下代码使用 AES/CTR/NOPADDING 模式加密 java 中的一些文件内容。我正在使用 javax 的加密包。我也使用相同的密钥生成密钥和 iv.
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
byte[] secretKey = Base64.decodeBase64("uQsaW+WMUrjcsq1HMf+2JQ==");
SecretKeySpec key = new SecretKeySpec(secretKey, "AES");
IvParameterSpec iv = new IvParameterSpec(secretKey);
cipher.init(mode, key , iv);
FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
FileOutputStream fileOutputStream = new FileOutputStream(destFilePath);
int read = 0;
while ((fileInputStream.available()) > 0) {
byte[] block = new byte[4096];
read = fileInputStream.read(block);
byte[] writeBuffer = cipher.update(block);
fileOutputStream.write(writeBuffer, 0, read);
}
byte[] writeBuffer = cipher.doFinal();
fileOutputStream.write(writeBuffer, 0, writeBuffer.length);
fileInputStream.close();
fileOutputStream.close();
我无法使用 cryptojs 解密 java 脚本中的加密内容。 这是我试过的东西。
var key = CryptoJS.enc.Hex.parse(atob('uQsaW+WMUrjcsq1HMf+2JQ=='));
var decrypted = CryptoJS.AES.decrypt(encryptedContent, key, {
mode: CryptoJS.mode.CTR,
iv: key,
padding: CryptoJS.pad.NoPadding
});
var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted);
有人可以告诉我我做错了什么吗?或者告诉我怎么做。
我可以在 java 和 java 脚本中独立加密和解密。
你的加密循环是错误的。我不确定这是否是您问题的原因,但我会从它开始
read = fileInputStream.read(block);
byte[] writeBuffer = cipher.update(block);
即使你只读取块的部分大小,对整个块执行加密操作,你可以尝试
byte[] writeBuffer = cipher.update(block, 0, read);
关于使用密钥作为 IV,我必须强调,使用 CTR 模式,安全性将被完全破坏。
在
CryptoJS
-documentation 中解释了CryptoJS.decrypt()
方法需要哪些数据类型和参数以及哪些编码器可用:- 密钥必须作为
WordArray
传递给CryptoJS.decrypt()
方法。由于密钥数据是 Base64 编码的,因此可以使用CryptoJS.enc.Base64.parse()
方法将它们转换为WordArray
。 - 密文可以作为
CipherParams
对象中的WordArray
传递给CryptoJS.decrypt()
方法。 Java-代码将加密数据存储在文件中。假设字符串encryptedContent
包含这些数据作为十六进制字符串(不幸的是,这不会从发布的代码中出现,因此必须在此处进行假设),它们可以转换为WordArray
CryptoJS.enc.Hex.parse()
-方法并包装在CipherParams
-对象中。 CryptoJS.decrypt()
-方法returns一个WordArray
可以用CryptoJS.enc.Utf8.stringify()
-方法转换成字符串。
- 密钥必须作为
如果输入文件中包含以下纯文本:
This is the plain text which needs to be encrypted!
Java代码在输出文件中存储以下字节序列(=加密数据):
52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7
解密的Java脚本代码是:
var key = CryptoJS.enc.Base64.parse('uQsaW+WMUrjcsq1HMf+2JQ=='); var encryptedContent = '52F415AB673427C42278E8D6F34C16134D7E3FE7986500980ED4063F3CF51162592CE0F5412CCA0BC2DBAE3F2AEC2D585EE8D7'; var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Hex.parse(encryptedContent) }); var decrypted = CryptoJS.AES.decrypt(cipherParams, key, { mode: CryptoJS.mode.CTR, iv: key, padding: CryptoJS.pad.NoPadding }); var decryptedText = CryptoJS.enc.Utf8.stringify(decrypted); console.log(decryptedText);
在控制台显示原始纯文本。要 运行 上面的代码至少需要 CryptoJS 版本 3.1.4(参见 versions, cdnjs)。