当前位置: 首页 > 知识库问答 >
问题:

Java中的AES加密无法在Javascript中解密

鲁涵意
2023-03-14

我正在使用AES-256(AES/CBC/PKCS5Padding)使用基于密码的加密(PBKDF2WithHmacSHA1)。

在Java中,我使用了以下加密和解密代码,它工作得很好。

String password = "MyPassword1";
String salt = "MysaltString"; //Will switch to random salt generation.
String plainText = "Quick Brown Fox";


SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));

/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
var password = "MyPassword1";
var salt = "MysaltString"; //Will switch to random salt generation.

var derivedKey = forge.pkcs5.pbkdf2(password, salt, 1024, 32);
input = forge.util.createBuffer(encrypted);
var decipher = forge.cipher.createDecipher('AES-CBC', derivedKey);
decipher.start({iv: iv});
decipher.update(input);
res = decipher.finish();

我的猜测是它与提供给JS的输入格式有关(密码,salt,IV,encrptedtext),我只是不知道它是否必须是base64,十六进制等等。

共有1个答案

漆雕稳
2023-03-14

原因是Java使用带符号的字节。您应该在IV和密文的JavaScript端使用two's补码。您的JS代码应该如下所示:

var password = "MyPassword1";
var salt = "MysaltString";
var derivedKey = forge.pkcs5.pbkdf2(password, salt, 1024, 32);

for (var i = 0; i < iv_in.length; i++) {
    iv_in[i] = (iv_in[i] & 0xFF);
}

var iv = String.fromCharCode.apply(String, iv_in);

for (var i = 0; i < encrypted.length; i++) {
    encrypted[i] = (encrypted[i] & 0xFF);
}

var input_c = String.fromCharCode.apply(String, encrypted)

var input = forge.util.createBuffer(input_c);
var decipher = forge.cipher.createDecipher('AES-CBC', derivedKey);
decipher.start({iv: iv});
decipher.update(input);
var res = decipher.finish();

if (res) {
    console.log(decipher.output.toString('utf8'));
}

其中iv_inencrypted是从Java接收的输入字节数组,例如:

var iv_in=[24,-54,-15,5,106,-44,20,10,103,-62,-88,28,75,-68,-12,-14];

而且

VAR加密=[20,-56,117,80,-91,-104,22,-43,-127,-87,7,113,66,85,105,-25]

 类似资料:
  • 问题内容: 我有一个现有的网络服务,可以使用AES进行加密和解密,现在我必须以与Java相同的方式进行加密,但是要使用javascript。我已经阅读了有关在javascript中执行此操作的所有主题,但尚未找到任何有用的解决方案。Javascript总是以不同的方式加密,我找不到原因。 这是现有的java代码: 这是我倾向于使用的javascript代码,但是提供了不同的加密(CryptoJS)

  • 我已经使用OpenSSL AES-256-GCM加密了一个文件。由于aes-256-gcm不受命令行支持,我已经安装了LibreSSL,我可以使用下面的命令加密文件的数据。 openssl ENC-AES-256-GCM-K 616161616161616161616161616161616161616161616161616161616161616161-IV 768A5C31A97D5FE9-

  • 问题内容: 我一直在尝试使用AES-128 CBC解密字符串,该字符串最初是使用JAVA AES加密加密的。在Java中,使用PKCS7填充。而且我尝试使用类似的PHP代码进行加密和解密。但是我得到了不同的结果。 我的Java代码 以及我正在使用的等效PHP代码。 在Java中 纯文本= 123456 密码文本= tpyxISJ83dqEs3uw8bN / + w =​​= 在PHP中 纯文本=

  • 我一直在尝试使用AES-128 CBC解密一个字符串,它最初是使用JAVA AES加密加密的。在java中,使用了PKCS7填充。我试着用类似的PHP代码进行加密和解密。但我得到了不同的结果。 我的Java代码 以及我正在使用的等效PHP代码。 在Java 纯文本=123456 密码文本=tpyxISJ83dqEs3uw8bN/w== 在PHP中 纯文本=123456 密码文本=ierqftckt

  • 问题内容: 我正在尝试在java中加密数据并在ruby中解密数据。 我的代码是…用Java加密 结果是 我希望在Ruby中解密(加密的字符串) Ruby代码是…(错误) 我希望得到 但它返回错误 我认为问题是cipher.padding和key / iv的类型。但是我不知道如何完成红宝石代码。 请让我知道如何完成此代码。 谢谢。 问题答案: Ruby代码有两个问题。 首先,应该使用AES 128时

  • 我正在尝试使用Javascript和CryptoJS复制Java应用程序中使用的加密。我不太确定应该如何复制SecretKeySpec,因为CryptoJS似乎需要一个字符串作为密钥。 下面是我需要在JS中复制的Java加密代码: 到目前为止,我的JS代码: 此外,密码的最终输出是一个加密的字节数组。CryptoJS的最终输出似乎是一个带有密文的对象。有没有办法以字节数组的形式获取输出? 我现在唯