如何在java服务器端解密cryptojs AES加密消息? [英] How to decrypt a cryptojs AES encrypted message at the java server side?
问题描述
我有以下基于加密的javascript加密/解密功能,工作完美。
I have the following cryptojs based javascript encryption/decryption functions which works perfectly fine.
我使用随机盐,随机的iv值和特定的密码,同时使用cryptpjs加密消息。我重新使用相同的盐,iv和密码来生成密钥,同时解密加密的邮件。
I use a random salt, random iv value and a specific password while encrypting the message using cryptpjs. I reuse the same salt, iv and the password to generate the key while decrypting the encrypted message.
这部分工作得很好..
This part works well..
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代码:
But the issue starts when I try to decrypt the same encrypted text at the java server side. I want the encrypted message to be decrypted by my java server code. Here is the Java code that I wrote:
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
值是错误的。您需要 128
, 192
或 256
。目前您的价值相当于 4
,这似乎导致PBKDF2功能无法输出。
The 128/32
value is erroneous. You need either 128
, 192
or 256
. Currently you have the equivalent of 4
, which seems to result in no output at all from the PBKDF2 function.
此外,在Java中,您应该使用 DatatypeConverter.parseHexBinary()
或类似的,将hex转换为字节。目前你只是调用 getBytes()
这是不正确的。
Also, in Java you should use DatatypeConverter.parseHexBinary()
, or similar, to convert hex into bytes. Currently you are just calling getBytes()
which isn't right.
最后,您需要指定CBC模式和PKCS#5填充,以匹配您的Javascript代码。所以更改行到:
Finally, you need to specify CBC mode and PKCS#5 padding in order to match your Javascript code. So change the line to:
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
这篇关于如何在java服务器端解密cryptojs AES加密消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!