在JavaScript中加密AES-GCM,用Java解密

时间:2017-11-09 16:16:22

标签: javascript java encryption cryptography aes-gcm

我们正在使用SJCL(Stanford Javascript Crypto Library)在JavaScript中加密,我们应该用Java实现解密。

加密代码如下所示:

<script src='https://cdnjs.cloudflare.com/ajax/libs/sjcl/1.0.7/sjcl.js'></script>

<script>
var keyString = '2d73c1dd2f6a3c981afc7c0d49d7b58f';
var key = sjcl.codec.base64.toBits(keyString);
var cipher = new sjcl.cipher.aes(key)
var data = sjcl.codec.utf8String.toBits('Hello Crypto!'); 
var salt = sjcl.codec.base64url.toBits('kLME6vN-WdU_W9XVN9a1Z3E_p8HQ5C7X1La-3ZjEml1ytVRMfvtEXzeapbce2LjFI1dHEGtWv9bZ_U6K2CG1-K4lQPunFXWxXmsTQIXlGfwmpveg2AFeLFiqGmALnfbP');
var encrypted = sjcl.encrypt(keyString,'Hello Crypto!',{mode:'gcm',salt:salt});

console.log(encrypted)
</script>

生成的加密如下所示:

{
   "iv":"+xmg3yZF/LSWNFpXf03wUw==",
   "v":1,
   "iter":10000,
   "ks":128,
   "ts":64,
   "mode":"gcm",
   "adata":"",
   "cipher":"aes",
   "salt":"kLME6vN+WdU/W9XVN9a1Z3E/p8HQ5C7X1La+3ZjEml1ytVRMfvtEXzeapbce2LjFI1dHEGtWv9bZ/U6K2CG1+K4lQPunFXWxXmsTQIXlGfwmpveg2AFeLFiqGmALnfbP",
   "ct":"Nq+9tXfc0zs0/m3OfDp0MmTXc9qD"
}

我们提供了示例Java代码来解密代码,但是这段代码假设IV和salt是相同的,所以它不能使用我们从JS库获得的JSON(具有IV和盐)作为两个单独的值):

 final byte[] symKeyData = DatatypeConverter.parseHexBinary(keyHex);
 final byte[] ivData = ivSalt.getBytes(Charset.forName("UTF-8"));
 final byte[] encryptedMessage = DatatypeConverter.parseBase64Binary(encryptedMessageString);
 final Cipher cipher = javax.crypto.Cipher.getInstance("AES/GCM/NoPadding", "BC");
 final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
 final IvParameterSpec iv = new IvParameterSpec(ivData);
 cipher.init(Cipher.DECRYPT_MODE, symKey, iv);
 final byte[] encodedMessage = cipher.doFinal(encryptedMessage);
 final String message = new String(encodedMessage, Charset.forName("UTF-8"));

有人可以解释如何在Java中正确解密JavaScript库中生成的JSON吗?

1 个答案:

答案 0 :(得分:3)

SJCL便利库使用PBKDF2进行1000次迭代来导出密钥。可以找到文档和代码here

但是,如果这是一项任务:

  • IV是错误的大小,它应该是12个字节,而不是16;
  • 盐的大小太大了;
  • 完全忽略JavaScript中的cipher变量;
  • 迭代计数保留为默认值,通常被认为太低。

所以我不知道是谁写的,但他们不应该发布这样的代码。

盐用于PBKDF2,IV用于对称密码,因此它们不相同。