如何解密使用JS加密加密的Java字符串

时间:2014-10-20 08:18:11

标签: java javascript encryption

使用javax.crypto.xxx,Java中的这个JS代码相当于什么?

    encryptString : function encryptString(str, password) {
        var cipher = crypto.createCipher("aes128", password);
        return cipher.update(str, "binary", "base64") +
            cipher.final("base64");
    },

    decryptString : function decryptString(str, password) {
        var desipher = crypto.createDecipher("aes128", password);
        return desipher.update(str, "base64", "binary") +
            desipher.final("binary");
    }

我将在JS中编码以在Java中解码,反之亦然。 'str'和'password'变量都是字符串,'password'是16个字符长。

看起来这个createCipher(算法,密码)方法使用某种方法生成原始密钥和IV,这不是全面的标准。我认为使用createCipheriv(算法,密钥,iv)将是一种更便携的方法。 更多信息:http://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv 我很快就会更新最新版本。

2 个答案:

答案 0 :(得分:0)

这是分别使用Crypto和javax.crypto在JS和Java中加密/解密的方法。

如果您不关心不同环境的互操作性,您可以在JS代码中使用createCypher(algorithm, password)快速入门,但它不是非常便携,因为您不知道原始密钥和初始化向量源自密码。

更改JS代码以使用createCipheriv(algorithm, key, iv)代替,将为您提供便携式加密/解密:

    encryptString : function encryptString(str, encryptionKey, iv) {
        var cipher = crypto.createCipheriv('aes-128-cbc', encryptionKey, iv);
        var cipherText = cipher.update(str, 'binary', 'base64');
        var cipherTextRemaining = cipher.final('base64');
        return cipherText + cipherTextRemaining;
    },

    decryptString : function decryptString(str, encryptionKey, iv) {
        var desipher = crypto.createDecipheriv('aes-128-cbc', encryptionKey, iv);
        var desipherText = desipher.update(str, 'base64', 'binary');
        var desipherTextRemaining = desipher.final('binary');
        return desipherText + desipherTextRemaining;
    },

这是完全相同的Java代码:

public static String encryptString(String clearText, byte[] key, byte[] initialVector) throws Exception
{
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec secretKeySpecy = new SecretKeySpec(key, "AES");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpecy, ivParameterSpec);
    byte[] encrypted = cipher.doFinal(clearText.getBytes());
    return new String(Base64.encodeBase64(encrypted, false));
}

public static String decryptString(String cipherText, byte[] key, byte[] initialVector) throws Exception
{
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec secretKeySpecy = new SecretKeySpec(key, "AES");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
    return new String(cipher.doFinal(Base64.decodeBase64(cipherText)));
}

答案 1 :(得分:0)

我们遇到了类似的问题。所以我们想要的是加密Java端的voucherCode并将其发送到前端。需要加密才能使凭证代码安全。

现在在前端,第三方java脚本库需要这个voucherCode,这样它应该能够通过解密来检索实际的voucherCode。

所以这就是我们所做的

在java方面

import javax.xml.bind.DatatypeConverter;

    public class Controller{

     @RequestMapping("voucherCode")
     public String getVoucherCode{
       String voucherCode = voucherService.getVoucherCode()
             return  DatatypeConverter.printBase64Binary(voucherCode.getBytes("UTF-8"))

}
    }

因此,如果我们将优惠券代码作为50%折扣,那么上述代码将发送NTAlT0ZG作为编码值50%OFF。

现在我们在前端有了编码值。 在javascript中,我们可以使用

获取原始值
window.atob("NTAlT0ZG") // this will return 50%OFF

所以这样我们可以在java和java脚本之间携手加密/解密。

window对象提供了两种加密和解密方法

 window.btoa("50%OFF") // returns NTAlT0ZG
    window.atob("NTAlT0ZG") // return original value as "50%OFF"