gpt4 book ai didi

java - 如何在 java 服务器端解密 cryptojs AES 加密消息?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:33:20 25 4
gpt4 key购买 nike

我有以下基于 cryptojs 的 javascript 加密/解密函数,它们工作得很好。

我在使用 cryptpjs 加密消息时使用随机盐、随机 iv 值和特定密码。在解密加密消息时,我重复使用相同的盐、iv 和密码来生成 key 。

这部分效果很好..

function  encrypt(){
var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);
console.log('salt '+ salt );
console.log('iv '+ iv );
var key128Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 });
console.log( 'key128Bits '+ key128Bits);
var key128Bits100Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 });
console.log( 'key128Bits100Iterations '+ key128Bits100Iterations);
var encrypted = CryptoJS.AES.encrypt("Message", key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
console.log('encrypted '+ encrypted );
}

function decrypt(){
var salt = CryptoJS.enc.Hex.parse("4acfedc7dc72a9003a0dd721d7642bde");
var iv = CryptoJS.enc.Hex.parse("69135769514102d0eded589ff874cacd");
var encrypted = "PU7jfTmkyvD71ZtISKFcUQ==";
console.log('salt '+ salt );
console.log('iv '+ iv );
var key = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 });
console.log( 'key '+ key);
var decrypt = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
var ddd = decrypt.toString(CryptoJS.enc.Utf8);
console.log('ddd '+ddd);
}

但是当我尝试在 Java 服务器端解密相同的加密文本时,问题就开始了。我希望加密的消息被我的 java 服务器代码解密。这是我编写的 Java 代码:

public static void main(String args[]) throws Exception{
String password = "Secret Passphrase";
String salt = "4acfedc7dc72a9003a0dd721d7642bde";
String iv = "69135769514102d0eded589ff874cacd";
String encrypted = "PU7jfTmkyvD71ZtISKFcUQ==";
byte[] saltBytes = salt.getBytes(); //hexStringToByteArray(salt);
byte[] ivBytes = iv.getBytes();//hexStringToByteArray(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes);
System.out.println( decrypt( encrypted , sKey ,ivParameterSpec));
}

public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException {

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return new SecretKeySpec(secretKey.getEncoded(), "AES");
}

public static String decrypt(String encryptedData, SecretKeySpec sKey, IvParameterSpec ivParameterSpec) throws Exception {

Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sKey, ivParameterSpec);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}

但我得到以下异常:

Exception breakpoint: SecretKeySpec.java:96, java.lang.IllegalArgumentException, Empty key
Exception in thread "main" java.lang.IllegalArgumentException: Empty key
at javax.crypto.spec.SecretKeySpec.<init>(SecretKeySpec.java:96)

我不知道我该做什么

最佳答案

这部分代码是错误的:

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32);
//->---------------------------------------------------------------------^^^^^^^

128/32 值是错误的。您需要 128192256。目前你有 4 的等价物,这似乎导致 PBKDF2 函数根本没有输出。

另外,在 Java 中你应该使用 DatatypeConverter.parseHexBinary() ,或类似的,将十六进制转换为字节。目前您只是在调用 getBytes(),这是不对的。

最后,您需要指定 CBC 模式和 PKCS#5 填充以匹配您的 Javascript 代码。所以将行更改为:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

关于java - 如何在 java 服务器端解密 cryptojs AES 加密消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27248644/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com