javascript - Node JS 中的 AES 加密/解密类似于 Java

标签 javascript java node.js cryptography cryptojs

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

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");
        }
    }

NodeJS

    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 中获得了这一点。

最佳答案

您的代码实际上在这两种情况下使用了不同的加密参数。 AES 是一种分组密码,采用:要加密的纯文本、初始化 vector (也称为 IV(与纯文本结合使用))以及加密 key 。

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

The generated parameters can be retrieved using getParameters or getIV (if the parameter is an IV).

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

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

  • 双方使用相同的加密算法 - 最好准确指定这一点,例如 aes-256-cbc,或经过身份验证的加密方案,例如 aes-256-gcm,使用起来比较困难,但提供消息身份验证。
  • 在 Java 中通过在初始化参数中提供相同的 IV,并在 Node 中使用 createCipheriv 来在两侧使用相同的 IV;但请注意,您应该始终在生产中将其随机化!请参阅https://stackoverflow.com/a/20888967/6098312

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

关于javascript - Node JS 中的 AES 加密/解密类似于 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60283479/

相关文章:

javascript - 如何在嵌套的html文件中执行脚本代码?

javascript - jquery 在表单中选择 div 类并添加值

java - JSON 响应中的属性可以有多种类型

javascript - 继承不存在的 ES6 模型方法

javascript - 如何在 Github Issue on create (API) 上发表评论

javascript - 对 chrome 和其他浏览器的 react

java - 在 HTTP 请求中设置 UTC 时间

java - 使用 Tomcat 和 Mysql 将应用程序部署到 Heroku 时出错

node.js - 是否可以让 IRC 客户端使用 websockets 运行您自己的 IRC 服务器而无需 websockets 网关?

android - Ubuntu 16/Cordova 6.4/Android : Could not resolve com. android.tools.build:gradle