简体   繁体   English

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

[英]AES Encryption/Decryption in Node JS similar to Java

I am trying to replicate the Java code for AES Encryption and Decryption in Node JS .我正在尝试在Node JS 中复制用于AES 加密和解密Java代码。

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

Node JS节点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;
    }

I am unable to get the exact cipher-text in Node JS , which i am getting in Java .我无法在Node JS 中获得确切的密文,而我在Java 中获得了。

Your code actually uses different encryption parameters in the 2 cases.您的代码实际上在两种情况下使用了不同的加密参数。 AES, being a block cipher, takes: the plain text to encrypt, the initialization vector, also called IV (which is used in conjunction with the plaintext), and the encryption key.作为分组密码的 AES 需要:要加密的明文、初始化向量,也称为 IV(与明文结合使用)和加密密钥。

In Java, the IV is, apparently, generated automatically on init() - from the Java SE platform docs for Cipher.init:在 Java 中,IV 显然是在init()上自动生成的——来自 Cipher.init 的 Java SE 平台文档:

The generated parameters can be retrieved using getParameters or getIV (if the parameter is an IV).可以使用 getParameters 或 getIV(如果参数是 IV)检索生成的参数。

In Node.js, if using the deprecated createCipher function, the IV is generated automatically based on the provided key, probably in a different way than in Java, so you will get a different cipher text.在 Node.js 中,如果使用已弃用的 createCipher函数,IV 将根据提供的密钥自动生成,可能与 Java 中的方式不同,因此您将获得不同的密文。 However, you should be using the non-deprecated variant crypto.createCipheriv : https://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options但是,您应该使用未弃用的变体crypto.createCipherivhttps : //nodejs.org/docs/latest-v12.x/​​api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options

In order to exactly reproduce the cipher text, you should:为了准确重现密文,您应该:

  • Use the same encryption algorithm on both sides - it's best to specify this exactly, for example aes-256-cbc , or an authenticated encryption scheme such as aes-256-gcm , which is harder to use but provides message authentication.在双方使用相同的加密算法 - 最好准确指定这一点,例如aes-256-cbc或经过身份验证的加密方案,例如aes-256-gcm ,它更难使用但提供消息身份验证。
  • Use the same IV on both sides, by providing it in the initialization params in Java, and by using createCipheriv in Node;在双方使用相同的 IV,通过在 Java 中的初始化参数中提供它,并在 Node 中使用createCipheriv though beware, you should always randomize it in production!但要注意,您应该始终在生产中随机化它! See https://stackoverflow.com/a/20888967/6098312https://stackoverflow.com/a/20888967/6098312

As a closing remark, when using block encryption, you'll usually be generating securely-random IVs, which means the ciphertexts will always differ from one another, even for the same plaintext.作为结束语,当使用块加密时,您通常会生成安全随机的 IV,这意味着密文将始终彼此不同,即使对于相同的明文。 This is a good thing!这是一件好事! It protects your payload from an attacker who observes the encrypted data and makes conclusions based on message repetitions.它可以保护您的有效负载免受观察加密数据并根据消息重复做出结论的攻击者的攻击。

Finally after reviewing Java Docs and Node JS Crypto Docs managed to get the result.最后在查看Java DocsNode JS Crypto Docs 后设法得到了结果。 We have to use crypto.createCipheriv() instead of crypto.createCipher with a iv.我们必须使用crypto.createCipheriv()而不是带有iv 的crypto.createCipher Here iv will be null .这里 iv 将为null

Code :代码 :

    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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM