【问题标题】:AES Encryption/Decryption in Node JS similar to Java类似于 Java 的 Node JS 中的 AES 加密/解密
【发布时间】:2020-02-18 14:45:58
【问题描述】:

我正在尝试在 Node JS 中复制 Java 代码以用于 AES 加密和解密

Java 代码

    SecretKeySpec skeySpec;
    String key = "a4e1112f45e84f785358bb86ba750f48";

    public void encryptString(String key) throws Exception {
        try {
            skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            cipher = Cipher.getInstance("AES");
            cipher.init(1, skeySpec);
            byte encstr[] = cipher.doFinal(message.getBytes());
            String encData = new String(encstr, "UTF-8");
            System.out.println(encData);
        } catch (NoSuchAlgorithmException nsae) {
            throw new Exception("Invalid Java Version");
        } catch (NoSuchPaddingException nse) {
            throw new Exception("Invalid Key");
        }
    }

节点 JS

    var encryptKey = function (text) {
        var cipher = crypto.createCipher('aes256', 'a4e1112f45e84f785358bb86ba750f48');
        var crypted = cipher.update(text,'utf8', 'hex')
        crypted += cipher.final('hex');
        console.log(crypted);
        return crypted;
    }

我无法在 Node JS 中获得准确的 密文,而我在 Java 中获得了该信息。

【问题讨论】:

  • Whey-hey,另一个绝对一切出错的加密示例。 ECB 模式,作为字符串的密钥(十六进制,但未解码),糟糕的异常处理甚至没有注册原因并使用错误消息和使用异常等,明文编码错误以及为什么不使用 ECB 来保证传输模式的安全性。每行至少有一个错误,请勿使用上述代码。

标签: javascript java node.js cryptography cryptojs


【解决方案1】:

您的代码在这两种情况下实际上使用了不同的加密参数。 AES 是一种分组密码,它采用:要加密的纯文本、初始化向量,也称为 IV(与纯文本一起使用)和加密密钥。

在 Java 中,IV 显然是在 init() 上自动生成的——来自 Cipher.init 的 Java SE 平台文档:

可以使用 getParameters 或 getIV 检索生成的参数 (如果参数是 IV)。

在 Node.js 中,如果使用 deprecated createCipher 函数,IV 会根据提供的密钥自动生成,可能与 Java 中的方式不同,因此您将获得不同的密文.但是,您应该使用未弃用的变体 crypto.createCipherivhttps://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options

为了准确再现密文,您应该:

  • 在双方使用相同的加密算法 - 最好准确指定,例如 aes-256-cbc,或经过身份验证的加密方案,例如 aes-256-gcm,它更难使用,但提供消息身份验证。
  • 在两边使用相同的 IV,通过在 Java 的初始化参数中提供它,并在 Node 中使用 createCipheriv;虽然要小心,但您应该始终在生产中随机化它!见https://stackoverflow.com/a/20888967/6098312

作为结束语,在使用块加密时,您通常会生成安全随机的 IV,这意味着密文将始终彼此不同,即使对于相同的明文也是如此。这是一件好事!它可以保护您的有效负载免受攻击者观察加密数据并根据消息重复得出结论。

【讨论】:

【解决方案2】:

最后在查看了Java DocsNode JS Crypto Docs后,终于得到了结果。 我们必须使用crypto.createCipheriv() 而不是crypto.createCipher 和iv。 这里 iv 将是null

代码:

    let crypto = require('crypto');

    var iv = new Buffer.from('');   //(null) iv 
    var algorithm = 'aes-256-ecb';
    var password = 'a4e1112f45e84f785358bb86ba750f48';      //key password for cryptography

    function encrypt(buffer){
        var cipher = crypto.createCipheriv(algorithm,new Buffer(password),iv)
        var crypted = Buffer.concat([cipher.update(buffer),cipher.final()]);
        return crypted;
    }

    console.log(encrypt(new Buffer('TextToEncrypt')).toString())

【讨论】:

    猜你喜欢
    • 2018-01-04
    • 1970-01-01
    • 2015-04-21
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2013-04-19
    • 2019-10-27
    相关资源
    最近更新 更多