助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
# 加密(Crypto) ~~~ 稳定度: 2 - 不稳定;正在讨论未来版本的API变动。会尽量减少重大变动的发生。详见下文。 ~~~ 使用 `require('crypto')` 来调用该模块。 crypto模块提供在HTTPS或HTTP连接中封装安全凭证的方法. 它提供OpenSSL中的一系列哈希方法,包括hmac、cipher、decipher、签名和验证等方法的封装。 ### crypto.getCiphers() 返回一个数组,包含支持的加密算法的名字。 实例: ~~~ var ciphers = crypto.getCiphers(); console.log(ciphers); // ['AES-128-CBC', 'AES-128-CBC-HMAC-SHA1', ...] ~~~ ### crypto.getHashes() 返回一个包含所支持的哈希算法的数组。 实例: ~~~ var hashes = crypto.getHashes(); console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] ~~~ ### crypto.createCredentials(details) 创建一个加密凭证对象,接受一个可选的参数对象: - `pfx` : 一个字符串或者buffer对象,代表经PFX或者PKCS12编码产生的私钥、证书以及CA证书 - `key` : 一个字符串,代表经PEM编码产生的私钥 - `passphrase` : 私钥或者pfx的密码 - `cert` : 一个字符串,代表经PEM编码产生的证书 - `ca` : 一个字符串或者字符串数组,表示可信任的经PEM编码产生的CA证书列表 - `crl` : 一个字符串或者字符串数组,表示经PEM编码产生的CRL(证书吊销列表 Certificate Revocation List) - `ciphers`: 一个字符串,表示需要使用或者排除的加密算法 可以在 [http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT](http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) 查看更多关于加密算法格式的资料。 如果没有指定`ca`,node.js会使用[http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt](http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt)提供的公共可信任的CA列表。 ### crypto.createHash(algorithm) 创建并返回一个哈希对象,一个使用所给算法的用于生成摘要的加密哈希。 `algorithm` 取决与平台上所安装的 OpenSSL 版本所支持的算法。比如 `'sha1'`、`'md5'`、`'sha256'`、`'sha512'` 等等。在最近的发行版本中,`openssl list-message-digest-algorithms` 会显示可用的摘要算法。 例子:这段程序会计算出一个文件的 sha1 摘要值。 ~~~ s.on('end', function() { var d = shasum.digest('hex'); console.log(d + ' ' + filename); }); ~~~ ### 类: Hash 创建数据哈希摘要的类。 它是一个既可读又可写的[流](#)。所写入的数据会被用作计算哈希。当流的可写端终止后,使用 `read()` 方法来获取计算得的哈希摘要。同时也支持旧有的 `update` 和 `digest` 方法。 通过 `crypto.createHash` 返回。 ### hash.update(data, [input_encoding]) 通过提供的数据更新哈希对象,可以通过`input_encoding`指定编码为`'utf8'`、`'ascii'`或者 `'binary'`。如果没有指定编码,将作为二进制数据(buffer)处理。 因为它是流式数据,所以可以使用不同的数据调用很多次。 ### hash.digest([encoding]) 计算传入的所有数据的摘要值。`encoding`可以是`'hex'`、`'binary'`或者`'base64'`,如果没有指定,会返回一个buffer对象。 注意:`hash` 对象在 `digest()` 方法被调用后将不可用。 ### crypto.createHmac(algorithm, key) 创建并返回一个hmac对象,也就是通过给定的加密算法和密钥生成的加密图谱(cryptographic)。 它是一个既可读又可写的流([stream](#))。写入的数据会被用于计算hmac。写入终止后,可以使用`read()`方法获取计算后的摘要值。之前版本的`update`和`digest`方法仍然支持。 `algorithm`在OpenSSL支持的算法列表中被抛弃了——见上方createHash部分。`key`是hmac算法用到的密钥。 ### Class: Hmac 用于创建hmac加密图谱(cryptographic)的类。 由`crypto.createHmac`返回。 ### hmac.update(data) 通过提供的数据更新hmac对象。因为它是流式数据,所以可以使用新数据调用很多次。 ### hmac.digest([encoding]) 计算传入的所有数据的hmac摘要值。`encoding`可以是`'hex'`、`'binary'`或者`'base64'`,如果没有指定,会返回一个buffer对象。 注意: `hmac`对象在调用`digest()`之后就不再可用了。 ### crypto.createCipher(algorithm, password) 用给定的算法和密码,创建并返回一个cipher加密算法的对象。(译者:cipher 就是加密算法的意思, ssl 的 cipher 主要是对称加密算法和不对称加密算法的组合。) `algorithm`算法是依赖OpenSSL库的, 例如: `'aes192'`算法等。在最近发布的版本, 执行命令 `openssl list-cipher-algorithms` 就会显示出所有可用的加密算法,`password`是用来派生key和IV的,它必须是一个 `'binary'` 2进制格式的字符串或者是一个[buffer](#)。(译者:key表示密钥,IV表示向量在加密过程和解密过程都要使用) 它是一个既可读又可写的[流](#)。所写入的数据会被用作计算哈希。当流的可写端终止后,使用 `read()` 方法来获取计算得的哈希摘要。同时也支持旧有的 `update` 和 `digest` 方法。 ### crypto.createCipheriv(algorithm, key, iv) 用给定的算法、密码和向量,创建并返回一个cipher加密算法的对象。 `algorithm`算法和`createCipher()` 方法的参数相同. `key`密钥是一个被算法使用的原始密钥,`iv`是一个[初始化向量](http://en.wikipedia.org/wiki/Initialization_vector)。 `key`密钥和`iv`向量必须是`'binary'`2进制格式的字符串或[buffers](#). ### Class: Cipher 这个类是用来加密数据的。 这个类由 `crypto.createCipher` 和 `crypto.createCipheriv` 返回。 Cipher加密对象是 [streams](#),他是具有 readable 可读和 writable 可写的。写入的纯文本数据是用来在可读流一侧加密数据的。 以前版本的`update` 和`final`方法也还是支持的。 ### cipher.update(data, [input_encoding], [output_encoding]) 用`data`参数更新cipher加密对象, 它的编码`input_encoding`必须是下列给定编码的 `'utf8'`, `'ascii'` or `'binary'` 中一种。如果没有编码参数,那么打他参数必须是一个buffer。 参数 `output_encoding`输出编码指定了加密数据的输出格式,可以是`'binary'`, `'base64'` 或者`'hex'`,如果没有提供这个参数,buffer将会返回。 返回加密内容,并且Returns the enciphered contents, 用新数据作为流的话,它可以被调用多次。 ### cipher.final([output_encoding]) 返回剩余的加密内容,`output_encoding`为`'binary'`, `'base64'` 或 `'hex'`中的任意一个。 如果没有提供编码格式,则返回一个buffer对象。 注: 调用`final()`函数后`cipher` 对象不能被使用。 ### cipher.setAutoPadding(auto_padding=true) 对于将输入数据自动填充到块大小的功能,你可以将其禁用。如果`auto_padding`是false, 那么整个输入数据的长度必须是加密器的块大小的整倍数,否则`final`会失败。这对非标准的填充很有用,例如使用`0x0`而不是PKCS的填充。这个函数必须在`cipher.final`之前调用。 ### crypto.createDecipher(algorithm, password) 根据给定的算法和密钥,创建并返回一个解密器对象。这是上述[createCipher()](#)的一个镜像。 ### crypto.createDecipheriv(algorithm, key, iv) Creates and returns a decipher object, with the given algorithm, key and iv. This is the mirror of the [createCipheriv()](#) above. 根据给定的算法,密钥和初始化向量,创建并返回一个解密器对象。这是上述[createCipheriv()](#)的一个镜像。 ### Class: Decipher 解密数据的类。 由`crypto.createDecipher`和`crypto.createDecipheriv`返回。 解密器对象是可读写的[流](#)对象。用被写入的加密数据生成可读的平文数据。解码器对象也支持The legacy `update`和 `final`函数。 ### decipher.update(data, [input_encoding], [output_encoding]) 用`data`来更新解密器,其中`data`以`'binary'`, `'base64'` 或 `'hex'`进行编码。如果没有指明编码方式,则默认`data`是一个buffer对象。 `output_decoding`指明了用以下哪种编码方式返回解密后的平文:`'binary'`, `'ascii'` 或 `'utf8'`。如果没有指明编码方式,则返回一个buffer对象。 ### decipher.final([output_encoding]) 返回剩余的加密内容,`output_encoding`为`'binary'`, `'ascii'` 或 `'utf8'`中的任意一个。如果没有指明编码方式,则返回一个buffer对象。 注: 调用`final()`函数后不能使用`decipher` 对象。 ### decipher.setAutoPadding(auto_padding=true) 如果数据以非标准的块填充方式被加密,那么你可以禁用自动填充来防止`decipher.final`对数据进行检查和移除。这只有在输入数据的长度是加密器块大小的整倍数时才有效。这个函数必须在将数据流传递给`decipher.update`之前调用。 ### crypto.createSign(algorithm) 根据给定的算法,创建并返回一个signing对象。在最近的OpenSSL发布版本中,`openssl list-public-key-algorithms`会列出可用的签名算法,例如`'RSA-SHA256'`。 ### Class: Sign 生成数字签名的类 由`crypto.createSign`返回。 Sign对象是可写的[流](#)对象。被写入的数据用来生成数字签名。当所有的数据都被写入后,`sign` 函数会返回数字签名。Sign对象也支持The legacy `update`函数。 ### sign.update(data) 用`data`来更新sign对象。 This can be called many times with new data as it is streamed. ### sign.sign(private_key, [output_format]) 根据所有传送给sign的更新数据来计算电子签名。`private_key`是一个包含了签名私钥的字符串,而该私钥是用PEM编码的。 返回一个数字签名,该签名的格式可以是`'binary'`, `'hex'`或 `'base64'`. 如果没有指明编码方式,则返回一个buffer对象。 注:调用`sign()`后不能使用`sign`对象。 ### crypto.createVerify(algorithm) 根据指明的算法,创建并返回一个验证器对象。这是上述签名器对象的镜像。 ### Class: Verify 用来验证数字签名的类。 由 `crypto.createVerify`返回。 验证器对象是可写的[流](#)对象. 被写入的数据会被用来验证提供的数字签名。在所有的数据被写入后,如果提供的数字签名有效,`verify`函数会返回真。验证器对象也支持 The legacy `update`函数。 ### verifier.update(data) 用数据更新验证器对象。This can be called many times with new data as it is streamed. ### verifier.verify(object, signature, [signature_format]) 用`object`和`signature`来验证被签名的数据。 `object`是一个字符串,这个字符串包含了一个被PEM编码的对象,这个对象可以是RSA公钥,DSA公钥或者X.509 证书。 `signature`是之前计算出来的数字签名,其中的 `signature_format`可以是`'binary'`, `'hex'` 或 `'base64'`. 如果没有指明编码方式,那么默认是一个buffer对象。 根据数字签名对于数据和公钥的有效性,返回true或false。 注: 调用`verify()`函数后不能使用`verifier`对象。 ### crypto.createDiffieHellman(prime_length) 创建一个迪菲-赫尔曼密钥交换(Diffie-Hellman key exchange)对象,并根据给定的位长度生成一个质数。所用的生成器是`s`。 ### crypto.createDiffieHellman(prime, [encoding]) 根据给定的质数创建一个迪菲-赫尔曼密钥交换(Diffie-Hellman key exchange)对象。 所用的生成器是`2`。编码方式可以是`'binary'`, `'hex'`或 `'base64'`。如果没有指明编码方式,则默认是一个buffer对象。 ### Class: DiffieHellman 创建迪菲-赫尔曼密钥交换(Diffie-Hellman key exchanges)的类。 由`crypto.createDiffieHellman`返回。 ### diffieHellman.generateKeys([encoding]) 生成迪菲-赫尔曼(Diffie-Hellman)算法的公钥和私钥,并根据指明的编码方式返回公钥。这个公钥可以转交给第三方。编码方式可以是 `'binary'`, `'hex'`或 `'base64'`. 如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding]) 以`other_public_key`作为第三方公钥来计算共享秘密,并返回这个共享秘密。参数中的密钥会以`input_encoding`编码方式来解读,而共享密钥则会用`output_encoding`进行编码。编码方式可以是`'binary'`, `'hex'`或 `'base64'`。如果没有提供输入的编码方式,则默认为一个buffer对象。 如果没有指明输出的编码方式,则返回一个buffer对象。 ### diffieHellman.getPrime([encoding]) 根据指明的编码格式返回迪菲-赫尔曼(Diffie-Hellman)质数,其中编码方式可以是`'binary'`, `'hex'` 或 `'base64'`。如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.getGenerator([encoding]) 根据指明的编码格式返回迪菲-赫尔曼(Diffie-Hellman)质数,其中编码方式可以是`'binary'`, `'hex'` 或 `'base64'`。如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.getPublicKey([encoding]) 根据指明的编码格式返回迪菲-赫尔曼(Diffie-Hellman)公钥,其中编码方式可以是`'binary'`, `'hex'` 或 `'base64'`。 如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.getPrivateKey([encoding]) 根据指明的编码格式返回迪菲-赫尔曼(Diffie-Hellman)私钥,其中编码方式可以是`'binary'`, `'hex'` 或 `'base64'`。如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.setPublicKey(public_key, [encoding]) 设置迪菲-赫尔曼(Diffie-Hellman)公钥,编码方式可以是可以是`'binary'`, `'hex'` 或 `'base64'`。如果没有指明编码方式,则返回一个buffer对象。 ### diffieHellman.setPrivateKey(private_key, [encoding]) 设置迪菲-赫尔曼(Diffie-Hellman)私钥,编码方式可以是可以是`'binary'`, `'hex'` 或 `'base64'`。如果没有指明编码方式,则返回一个buffer对象。 ### crypto.getDiffieHellman(group_name) 创建一个预定义的迪菲-赫尔曼密钥交换(Diffie-Hellman key exchanges)对象。支持以下的D-H组:`'modp1'`, `'modp2'`, `'modp5'` (在[RFC 2412](http://www.rfc-editor.org/rfc/rfc2412.txt)中定义) 和 `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`, `'modp18'` (在 [RFC 3526](http://www.rfc-editor.org/rfc/rfc3526.txt)中定义)。返回的对象模仿了上述 [crypto.createDiffieHellman()](#)方法所创建的对象的接口,但不会晕允许密钥交换 (例如像 [diffieHellman.setPublicKey()](#)那样)。执行这套流程的好处是双方不需要事先生成或交换组余数,节省了处理和通信时间。 例子 (获取一个共享秘密): ~~~ /* alice_secret和 bob_secret应该是一样的 */ console.log(alice_secret == bob_secret); ~~~ ### crypto.pbkdf2(password, salt, iterations, keylen, callback) 异步PBKDF2提供了一个伪随机函数 HMAC-SHA1,根据给定密码的长度,salt和iterations来得出一个密钥。回调函数得到两个参数 `(err, derivedKey)`。 ### crypto.pbkdf2Sync(password, salt, iterations, keylen) 同步 PBKDF2 函数。返回derivedKey或抛出一个错误。 ### crypto.randomBytes(size, [callback]) 生成密码学强度的伪随机数据。用法: ~~~ // 同步 try { var buf = crypto.randomBytes(256); console.log('有 %d 字节的随机数据: %s', buf.length, buf); } catch (ex) { // handle error } ~~~ ### crypto.pseudoRandomBytes(size, [callback]) 生成*非*密码学强度的伪随机数据。如果数据足够长的话会返回一个唯一的数据,但这个返回值不一定是不可预料的。基于这个原因,当不可预料性很重要时,这个函数的返回值永远都不应该被使用,例如在生成加密的密钥时。 用法与 `crypto.randomBytes`一模一样。 ### crypto.DEFAULT_ENCODING 对于可以接受字符串或buffer对象的函数的默认编码方式。默认值是`'buffer'`,所以默认使用Buffer对象。这是为了让crypto模块与默认`'binary'`为编码方式的遗留程序更容易兼容。 要注意,新的程序会期待buffer对象,所以使用这个时请只作为暂时的手段。 ### Recent API Changes 早在统一的流API概念出现,以及引入Buffer对象来处理二进制数据之前,Crypto模块就被添加到Node。 因为这样,与流有关的类中并没有其它Node类的典型函数,而且很多函数接受和返回默认的二进制编码的字符串,而不是Buffer对象。在最近的修改中,这些函数都被改成默认使用Buffer对象。 这对于某些(但不是全部)使用场景来讲是重大的改变。 例如,如果你现在使用Sign类的默认参数,然后在没有检查数据的情况下,将结果传递给Verify类,那么程序会照常工作。在以前,你会拿到一个二进制字符串,然后它传递给Verify对象;而现在,你会得到一个Buffer对象,然后把它传递给Verify对象。 但是,如果你以前是使用那些在Buffer对象上不能正常工作的字符串数据,或者以默认编码方式将二进制数据传递给加密函数的话,那你就要开始提供编码方式参数来指明你想使用的编码方式了。如果想准换回旧的风格默认使用二进制字符串,那么你需要把`crypto.DEFAULT_ENCODING`字段设为'binary'。但请注意,因为新的程序很可能会期望buffer对象,所以仅将此当做临时手段。