この記事では、nodejs の暗号化モジュールについて紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
関連する推奨事項: 「nodejs チュートリアル 」
暗号化モジュールは、HTTP または HTTPS 接続中にセキュリティ資格情報をカプセル化する方法を提供します。 OpenSSL のハッシュ、hmac、暗号化 (cipher)、復号化 (decopher)、署名 (sign)、検証 (verify) メソッドのカプセル化も提供されます。この記事では、暗号化について紹介します crypto
crypto
##[crypto.setEngine(engine[, flags])]
一部/すべての OpenSSL 関数のエンジンをロードして設定します (パラメーター フラグに従って設定)。 Engine は、エンジン共有ライブラリへの ID またはパスの場合があります。 Flags はオプションのパラメータです。デフォルト値は ENGINE_METHOD_ALL で、次のパラメータ (定数で定義) を 1 つ以上組み合わせることができます。 ()] サポートされている暗号化アルゴリズム名の配列を返します。 ENGINE_METHOD_RSA
ENGINE_METHOD_DSA
ENGINE_METHOD_DH
ENGINE_METHOD_RAND
ENGINE_METHOD_ECDH
ENGINE_METHOD_ECDSA
ENGINE_METHOD_CIPHERS
ENGINE_METHOD_DIGESTS
ENGINE_METHOD_STORE
ENGINE_METHOD_PKEY_METH
ENGINE_METHOD_PKEY_ASN1_METH
ENGINE_METHOD_ALL
ENGINE_METHOD_NONE
の配列を返します。サポートされているハッシュ アルゴリズム名。 var crypto = require('crypto');
console.log(crypto.getCiphers());
//[ 'aes-128-cbc', 'aes-128-ccm', 'aes-128-cfb', 'aes-128-cfb1', 'aes-128-cfb8', 'aes-128-ctr', 'aes-128-ecb', 'aes-128-gcm', 'aes-128-ofb', 'aes-128-xts', 'aes-192-cbc', 'aes-192-ccm', 'aes-192-cfb', 'aes-192-cfb1', 'aes-192-cfb8', 'aes-192-ctr', 'aes-192-ecb', 'aes-192-gcm', 'aes-192-ofb', 'aes-256-cbc', 'aes-256-ccm', 'aes-256-cfb', 'aes-256-cfb1', 'aes-256-cfb8', 'aes-256-ctr', 'aes-256-ecb', 'aes-256-gcm', 'aes-256-ofb', 'aes-256-xts', 'aes128', 'aes192', 'aes256', 'bf', 'bf-cbc', 'bf-cfb', 'bf-ecb', 'bf-ofb', 'blowfish', 'camellia-128-cbc', 'camellia-128-cfb', 'camellia-128-cfb1', 'camellia-128-cfb8', 'camellia-128-ecb', 'camellia-128-ofb', 'camellia-192-cbc', 'camellia-192-cfb', 'camellia-192-cfb1', 'camellia-192-cfb8', 'camellia-192-ecb', 'camellia-192-ofb', 'camellia-256-cbc', 'camellia-256-cfb', 'camellia-256-cfb1', 'camellia-256-cfb8', 'camellia-256-ecb', 'camellia-256-ofb', 'camellia128', 'camellia192', 'camellia256', 'cast', 'cast-cbc', 'cast5-cbc', 'cast5-cfb', 'cast5-ecb', 'cast5-ofb', 'des', 'des-cbc', 'des-cfb', 'des-cfb1', 'des-cfb8', 'des-ecb', 'des-ede', 'des-ede-cbc', 'des-ede-cfb', 'des-ede-ofb', 'des-ede3', 'des-ede3-cbc', 'des-ede3-cfb', 'des-ede3-cfb1', 'des-ede3-cfb8', 'des-ede3-ofb', 'des-ofb', 'des3', 'desx', 'desx-cbc', 'id-aes128-CCM', 'id-aes128-GCM', 'id-aes128-wrap', 'id-aes192-CCM', 'id-aes192-GCM', 'id-aes192-wrap', 'id-aes256-CCM', 'id-aes256-GCM', 'id-aes256-wrap', 'id-smime-alg-CMS3DESwrap', 'idea', 'idea-cbc', 'idea-cfb', 'idea-ecb', 'idea-ofb', ... 15 more items ]
サポートされている楕円曲線名の配列を返します。 var crypto = require('crypto');
console.log(crypto.getHashes());
//[ 'DSA', 'DSA-SHA', 'DSA-SHA1', 'DSA-SHA1-old', 'RSA-MD4', 'RSA-MD5', 'RSA-MDC2', 'RSA-RIPEMD160', 'RSA-SHA', 'RSA-SHA1', 'RSA-SHA1-2', 'RSA-SHA224', 'RSA-SHA256', 'RSA-SHA384', 'RSA-SHA512', 'dsaEncryption', 'dsaWithSHA', 'dsaWithSHA1', 'dss1', 'ecdsa-with-SHA1', 'md4', 'md4WithRSAEncryption', 'md5', 'md5WithRSAEncryption', 'mdc2', 'mdc2WithRSA', 'ripemd', 'ripemd160', 'ripemd160WithRSA', 'rmd160', 'sha', 'sha1', 'sha1WithRSAEncryption', 'sha224', 'sha224WithRSAEncryption', 'sha256', 'sha256WithRSAEncryption', 'sha384', 'sha384WithRSAEncryption', 'sha512', 'sha512WithRSAEncryption', 'shaWithRSAEncryption', 'ssl2-md5', 'ssl3-md5', 'ssl3-sha1', 'whirlpool' ]
MD5
MD5 は、データに「署名」を与えるために使用される一般的に使用されるハッシュ アルゴリズムです。この署名は通常、16 進数の文字列で表されます。
[crypto.createHash(algorithm)]指定されたアルゴリズムを使用してハッシュを生成し、ハッシュ オブジェクトを作成して返します。ダイジェストします。 パラメーターのアルゴリズムは、プラットフォーム上の OpenSSL バージョンでサポートされているアルゴリズムによって異なります。たとえば、「sha1」、「md5」、「sha256」、「sha512」などです。
【hash.update(data[, input_encoding])】データに従ってハッシュ内容を更新する エンコード方式は、「utf8」、「ascii」、または「binary」を含む input_encoding によって決定されます。値が渡されない場合、デフォルトのエンコードは「utf8」です。データがバッファの場合、input_encoding は無視されます。 これはストリーミング データであるため、異なるデータで何度も呼び出すことができます。
【hash.digest([encoding])】受信データのハッシュ ダイジェストを計算します。エンコーディングは「hex」、「binary」、または「base64」にすることができます。エンコーディングが指定されていない場合は、バッファが返されます。 【注意】digest()呼び出し後はハッシュオブジェクトを使用できません。
var crypto = require('crypto'); console.log(crypto.getCurves()); //[ 'Oakley-EC2N-3', 'Oakley-EC2N-4', 'brainpoolP160r1', 'brainpoolP160t1', 'brainpoolP192r1', 'brainpoolP192t1', 'brainpoolP224r1', 'brainpoolP224t1', 'brainpoolP256r1', 'brainpoolP256t1', 'brainpoolP320r1', 'brainpoolP320t1', 'brainpoolP384r1', 'brainpoolP384t1', 'brainpoolP512r1', 'brainpoolP512t1', 'c2pnb163v1', 'c2pnb163v2', 'c2pnb163v3', 'c2pnb176v1', 'c2pnb208w1', 'c2pnb272w1', 'c2pnb304w1', 'c2pnb368w1', 'c2tnb191v1', 'c2tnb191v2', 'c2tnb191v3', 'c2tnb239v1', 'c2tnb239v2', 'c2tnb239v3', 'c2tnb359v1', 'c2tnb431r1', 'prime192v1', 'prime192v2', 'prime192v3', 'prime239v1', 'prime239v2', 'prime239v3', 'prime256v1', 'secp112r1', 'secp112r2', 'secp128r1', 'secp128r2', 'secp160k1', 'secp160r1', 'secp160r2', 'secp192k1', 'secp224k1', 'secp224r1', 'secp256k1', 'secp384r1', 'secp521r1', 'sect113r1', 'sect113r2', 'sect131r1', 'sect131r2', 'sect163k1', 'sect163r1', 'sect163r2', 'sect193r1', 'sect193r2', 'sect233k1', 'sect233r1', 'sect239k1', 'sect283k1', 'sect283r1', 'sect409k1', 'sect409r1', 'sect571k1', 'sect571r1', 'wap-wsg-idm-ecid-wtls1', 'wap-wsg-idm-ecid-wtls10', 'wap-wsg-idm-ecid-wtls11', 'wap-wsg-idm-ecid-wtls12', 'wap-wsg-idm-ecid-wtls3', 'wap-wsg-idm-ecid-wtls4', 'wap-wsg-idm-ecid-wtls5', 'wap-wsg-idm-ecid-wtls6', 'wap-wsg-idm-ecid-wtls7', 'wap-wsg-idm-ecid-wtls8', 'wap-wsg-idm-ecid-wtls9' ]
Hmac
Hmac アルゴリズムはハッシュ アルゴリズムでもあり、MD5 や SHA1 などのハッシュ アルゴリズムを使用できます。違いは、Hmac にもキーが必要であることです。
[crypto.createHmac(algorithm, key)]指定されたアルゴリズムを使用して、hmac オブジェクトを作成して返します。 hmac マップを生成するための秘密キー。 読み書き可能なストリームストリームです。書き込まれたデータは hmac の計算に使用されます。ストリームへの書き込みが終了したら、read()メソッドを使用して計算値を取得します。古い更新方法とダイジェスト方法もサポートされています。
パラメーター アルゴリズムは、プラットフォーム上の OpenSSL バージョンでサポートされているアルゴリズムによって異なります。上記の createHash を参照してください。キーは hmac アルゴリズムで使用されるキーです。
【hmac.update(data)】データに基づいて hmac オブジェクトを更新します。ストリーミング データであるため、新しいデータで複数回呼び出すことができます。
【hmac.digest([encoding])】受信データの hmac 値を計算します。エンコーディングは「hex」、「binary」、または「base64」にすることができます。エンコーディングが指定されていない場合は、バッファが返されます。 [注意] Digest() を呼び出した後は hmac オブジェクトを使用できません。
var crypto = require('crypto'); var hash = crypto.createHash('md5'); // 可任意多次调用update(): hash.update('Hello, world!'); hash.update('Hello, nodejs!'); console.log(hash.digest('hex')); // 7e1977739c748beac0c0fd14fd26a544
AES
AES は一般的にused 暗号化と復号化の両方に同じキーを使用する対称暗号化アルゴリズム。暗号化モジュールは AES サポートを提供しますが、使いやすくするために関数を自分でカプセル化する必要があります。受信アルゴリズムと秘密キーを使用して、暗号化されたオブジェクトを生成して返します。 アルゴリズムは「aes192」などのOpenSSLに依存します。パスワードはキーと IV を導出するために使用されます。パスワードは「バイナリ」でエンコードされた文字列またはバッファである必要があります。
読み書き可能なストリームストリームです。書き込まれたデータは hmac の計算に使用されます。ストリームへの書き込みが終了したら、read()メソッドを使用して計算値を取得します。古い更新方法とダイジェスト方法もサポートされています。
【cipher.update(data[,input_encoding][,output_encoding])】
データに応じてハッシュ内容を更新します、input_encodingに応じてエンコード方式が決まります. 「utf8」「ascii」「binary」があります。値が渡されない場合、デフォルトのエンコードは「バイナリ」です。データがバッファの場合、input_encoding は無視されます。
output_encoding 指定了输出的加密数据的编码格式,它可用是 'binary', 'base64' 或 'hex'。如果没有提供编码,将返回 buffer 。
返回加密后的内容,因为它是流式数据,所以可以使用不同的数据调用很多次。
【cipher.final([output_encoding])】
返回加密后的内容,编码方式是由 output_encoding 指定,可以是 'binary', 'base64' 或 'hex'。如果没有传入值,将返回 buffer。
[注意]cipher 对象不能在 final() 方法之后调用。
var crypto = require('crypto'); function aesEncrypt(data, key) { const cipher = crypto.createCipher('aes192', key); var crypted = cipher.update(data, 'utf8', 'hex'); crypted += cipher.final('hex'); return crypted; } var data = 'Hello, this is a secret message!'; var key = 'Password!'; var encrypted = aesEncrypt(data, key); //8a944d97bdabc157a5b7a40cb180e713f901d2eb454220d6aaa1984831e17231f87799ef334e3825123658c80e0e5d0c console.log(encrypted);
【crypto.createDecipher(algorithm, password)】
根据传入的算法和密钥,创建并返回一个解密对象。这是 createCipher() 的镜像
【decipher.update(data[, input_encoding][, output_encoding])】
使用参数 data 更新需要解密的内容,其编码方式是 'binary','base64' 或 'hex'。如果没有指定编码方式,则把 data 当成 buffer 对象。
如果 data 是 Buffer,则忽略 input_encoding 参数。
参数 output_decoding 指定返回文本的格式,是 'binary', 'ascii' 或 'utf8' 之一。如果没有提供编码格式,则返回 buffer。
【decipher.final([output_encoding])】
返回剩余的解密过的内容,参数 output_encoding 是 'binary', 'ascii' 或 'utf8',如果没有指定编码方式,返回 buffer。
[注意]decipher对象不能在 final() 方法之后使用。
var crypto = require('crypto'); function aesDecrypt(encrypted, key) { const decipher = crypto.createDecipher('aes192', key); 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 encrypted = '8a944d97bdabc157a5b7a40cb180e713f901d2eb454220d6aaa1984831e17231f87799ef334e3825123658c80e0e5d0c'; var decrypted = aesDecrypt(encrypted, key); console.log(decrypted);//Hello, this is a secret message!
可以看出,加密后的字符串通过解密又得到了原始内容。
注意到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);
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算法如下:
var crypto = require('crypto'); // xiaoming's keys: var ming = crypto.createDiffieHellman(512); var ming_keys = ming.generateKeys(); var prime = ming.getPrime(); var generator = ming.getGenerator(); //Prime: 8df777257625c66821af697652f28e93af05b9f779af919111b89816faa11c36fcf9df04c76811471a6099800213c4fe8e3fbec8d2f90bd00795e4b7fd241603 console.log('Prime: ' + prime.toString('hex')); //Generator: 02 console.log('Generator: ' + generator.toString('hex')); // xiaohong's keys: var hong = crypto.createDiffieHellman(prime, generator); var hong_keys = hong.generateKeys(); // exchange and generate secret: var ming_secret = ming.computeSecret(hong_keys); var hong_secret = hong.computeSecret(ming_keys); //Secret of Xiao Ming: 4237157ab4c9211f78ffdb67d127d749cec91780d594b81a7e75f1fb591fecb84f33ae6591e1edda4bc9685b503010fe8f9928c6ed69e4ff9fdb44adb9ba1539 console.log('Secret of Xiao Ming: ' + ming_secret.toString('hex')); //Secret of Xiao Hong: 4237157ab4c9211f78ffdb67d127d749cec91780d594b81a7e75f1fb591fecb84f33ae6591e1edda4bc9685b503010fe8f9928c6ed69e4ff9fdb44adb9ba1539 console.log('Secret of Xiao Hong: ' + hong_secret.toString('hex'))
[注意]每次输出都不一样,因为素数的选择是随机的。
更多编程相关知识,请访问:编程视频!!
以上がNodejs の暗号化モジュールに関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。