如何在java服务器端解密cryptojs AES加密消息? [英] How to decrypt a cryptojs AES encrypted message at the java server side?

查看:143
本文介绍了如何在java服务器端解密cryptojs AES加密消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下基于加密的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆