【发布时间】:2021-05-08 17:01:46
【问题描述】:
我正在尝试重新创建从 JS 到 Java 的代码 sn-p,但输出不同。我究竟做错了什么? 这是来自 JS 的代码 sn-p:
var randomKey = 2116781760886580;
var key = CryptoJS.enc.Utf8.parse(randomKey);
var iv = CryptoJS.enc.Utf8.parse(randomKey);
var encrypt = CryptoJS.AES
.encrypt(CryptoJS.enc.Utf8.parse("Text to encrypt"), key,
{
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var out = btoa(encrypt); //SGpJSWhDUXNmMEMzSk0vbmovaGZyQT09
以下是Java代码sn-p:
String randomKey = "2116781760886580";
String plainText = "Text to encrypt";
byte[] keyBytes = randomKey.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
SecretKeySpec sKey = new SecretKeySpec(keyBytes,"AES");
cipher.init(Cipher.ENCRYPT_MODE, sKey, ivSpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
String out = Base64.getEncoder().encodeToString(encryptedBytes); //HjIIhCQsf0C3JM/nj/hfrA==
【问题讨论】:
-
您的密钥在 JS 中看起来像一个数字,而在 Java 中它是一个字符串(至少类型是这样说的,因为代码不是有效的 Java)。会不会有区别?
-
我认为,您在 js 代码中加密了两次。 CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("Text to encrypt") .... 但是在java代码中,你加密一次。
-
该错误在 CryptoJS 代码中。
CryptoJS.AES.encrypt()返回一个CipherParams对象,该对象封装了各种数据,包括密文。我不知道btoa对这个对象做了什么,但它不会返回 Base64 编码的密文。您可以使用encrypt.ciphertext.toString(CryptoJS.enc.Base64)或更短的encrypt.toString()获取它,它对应于Java 代码的Base64 编码密文。顺便说一句,使用密钥作为 IV 通常是不安全的。 -
@marstran 我在 JS 中通过使用字符串和数字类型打印单词数组来仔细检查,两个结果都是一样的。
-
@Topaco 好的,我正在尝试从 CryptoJs 中现有的实现在 Java 中重新创建相同的逻辑。
标签: javascript java encryption