注意到AES有很多不同的算法,如aes192,aes-128-ecb,aes-256-cbc等,AES除了密钥外还可以指定IV(Initial Vector),不同的系统只要IV不同,用相同的密钥加密相同的数据得到的加密结果也是不同的。
加密结果通常有两种表示方法:hex和base64,这些功能Nodejs全部都支持,但是在应用中要注意,如果加解密双方一方用Nodejs,另一方用Java、PHP等其它语言,需要仔细测试。
如果无法正确解密,要确认双方是否遵循同样的AES算法,字符串密钥和IV是否相同,加密后的数据是否统一为hex或base64格式
crypto.createCipheriv(algorithm, key, iv)创建并返回一个加密对象,用指定的算法,key 和 iv。
algorithm 参数和 createCipher() 一致。key 在算法中用到.iv 是一个initialization vector.
key 和 iv 必须是 'binary' 的编码字符串或buffers.
crypto.createDecipheriv(algorithm, key, iv)根据传入的算法,密钥和 iv,创建并返回一个解密对象。这是 createCipheriv() 的镜像。
const crypto = require('crypto'); function aesEncryptiv(data, key,iv) { const cipher = crypto.createCipher('aes192', key, iv); var crypted = cipher.update(data, 'utf8', 'hex'); crypted += cipher.final('hex'); return crypted; } function aesDecryptiv(encrypted, key,iv) { const decipher = crypto.createDecipher('aes192', key, iv); var decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } var data = 'Hello, this is a secret message!'; var key = 'Password!'; var iv = 'match'; var encrypted = aesEncryptiv(data, key, iv); var decrypted = aesDecryptiv(encrypted, key, iv); //Hello, this is a secret message! console.log(data); //8a944d97bdabc157a5b7a40cb180e713f901d2eb454220d6aaa1984831e17231f87799ef334e3825123658c80e0e5d0c console.log(encrypted); //Hello, this is a secret message! console.log(decrypted);
crypto Diffie-Hellman crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])使用传入的 prime 和 generator 创建 Diffie-Hellman 秘钥交互对象。
generator 可以是数字,字符串或Buffer。如果没有指定 generator,使用 2
prime_encoding 和 generator_encoding 可以是 'binary', 'hex', 或 'base64'。
如果没有指定 prime_encoding, 则 Buffer 为 prime。如果没有指定 generator_encoding ,则 Buffer 为 generator。
diffieHellman.generateKeys([encoding])生成秘钥和公钥,并返回指定格式的公钥。这个值必须传给其他部分。编码方式: 'binary', 'hex', 或 'base64'。如果没有指定编码方式,将返回 buffer。
diffieHellman.getPrime([encoding])用参数 encoding 指明的编码方式返回 Diffie-Hellman 质数,编码方式为: 'binary', 'hex', 或 'base64'。 如果没有指定编码方式,将返回 buffer。
diffieHellman.getGenerator([encoding])用参数 encoding 指明的编码方式返回 Diffie-Hellman 生成器,编码方式为: 'binary', 'hex', 或 'base64'. 如果没有指定编码方式 ,将返回 buffer。
diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])使用 other_public_key 作为第三方公钥来计算并返回共享秘密(shared secret)。秘钥用input_encoding 编码。编码方式为:'binary', 'hex', 或 'base64'。如果没有指定编码方式 ,默认为 buffer。
如果没有指定返回编码方式,将返回 buffer。
DH算法DH算法是一种密钥交换协议,它可以让双方在不泄漏密钥的情况下协商出一个密钥来。DH算法基于数学原理,比如小明和小红想要协商一个密钥,可以这么做:
1、小明先选一个素数和一个底数,例如,素数p=23,底数g=5(底数可以任选),再选择一个秘密整数a=6,计算A=g^a mod p=8,然后大声告诉小红:p=23,g=5,A=8;
2、小红收到小明发来的p,g,A后,也选一个秘密整数b=15,然后计算B=g^b mod p=19,并大声告诉小明:B=19;
3、小明自己计算出s=B^a mod p=2,小红也自己计算出s=A^b mod p=2,因此,最终协商的密钥s为2。
在这个过程中,密钥2并不是小明告诉小红的,也不是小红告诉小明的,而是双方协商计算出来的。第三方只能知道p=23,g=5,A=8,B=19,由于不知道双方选的秘密整数a=6和b=15,因此无法计算出密钥2。
用crypto模块实现DH算法如下: