稳定性: 2 - 不稳定; 正在讨论未来版本的 api 改进,会尽量减少重大变化。详见后文。
顾名思义,node.js加密模块允许你使用加密的功能,node.js加密模块通过使用require('crypto')
来访问。
node.js加密模块提供了http或https连接过程中封装安全凭证的方法。
node.js加密模块还提供了openssl的哈希,hmac、加密(cipher)、解密(decipher)、签名(sign)和验证(verify)方法的封装。
为某些/所有openssl函数加载并设置引擎(根据参数flags来设置)。
engine
可能是id,或者是指向引擎共享库的路径。
flags
是可选参数,默认值是engine_method_all
,它可以是以下一个或多个参数的组合(在constants
里定义):
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 ciphers = crypto.getciphers();
console.log(ciphers); // ['aes-128-cbc', 'aes-128-cbc-hmac-sha1', ...]
返回支持的哈希算法名数组。
例如:
var hashes = crypto.gethashes();
console.log(hashes); // ['sha', 'sha1', 'sha1withrsaencryption', ...]
稳定性: 0 - 抛弃。用 [tls.createsecurecontext][] 替换
根据参数details,创建一个加密凭证对象。参数为字典,key包括:
pfx
: 字符串或者buffer对象,表示经pfx或pkcs12编码产生的私钥、证书以及ca证书key
: 进过 pem 编码的私钥passphrase
: 私钥或pfx的密码cert
: pem编码的证书ca
: 字符串或字符串数组,pem编码的可信任的ca证书。crl
: 字符串或字符串数组,pem编码的crls(证书吊销列表certificate revocation list)。ciphers
: 字符串,使用或者排除的加密算法。参见http://www.openssl.org/docs/apps/ciphers.html#cipher_list_format。如果没有指定'ca',node.js将会使用下面列表中的cahttp://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt。
创建并返回一个哈希对象,使用指定的算法来生成哈希摘要。
参数algorithm
取决于平台的openssl版本所支持的算法。例如,'sha1'
、'md5'
、'sha256'
、'sha512'
等等。在最近的版本中,openssllist-message-digest-algorithms
会显示所有算法。
例如: 这个程序会计算文件的sha1的和。
var filename = process.argv[2];
var crypto = require('crypto');
var fs = require('fs');
var shasum = crypto.createhash('sha1');
var s = fs.readstream(filename);
s.on('data', function(d) {
shasum.update(d);
});
s.on('end', function() {
var d = shasum.digest('hex');
console.log(d + ' ' + filename);
});
hase用来生成数据的哈希值。
它是可读写的流stream。写入的数据来用计算哈希值。当写入流结束后,使用read()
方法来获取计算后的哈希值。也支持旧的update
和digest
方法。
通过crypto.createhash
返回。
根据data
来更新哈希内容,编码方式根据input_encoding
来定,有'utf8'
、'ascii'
或'binary'
。如果没有传入值,默认编码方式是'binary'
。如果 data
是buffer
,则input_encoding
将会被忽略。
因为它是流式数据,所以可以使用不同的数据调用很多次。
计算传入的数据的哈希摘要。
encoding
可以是'hex'
、'binary'
或'base64'
,如果没有指定encoding
,将返回buffer。
注意:调用digest()
后不能再用hash
对象。
创建并返回一个hmac对象,用指定的算法和秘钥生成hmac图谱。
它是可读写的流stream。写入的数据来用计算hmac。当写入流结束后,使用read()
方法来获取计算后的值。也支持旧的update
和digest
方法。
参数algorithm
取决于平台上openssl版本所支持的算法,参见前面的createhash。key
是hmac算法中用的key。
用来创建hmac加密图谱。
通过crypto.createhmac
返回。
根据data
更新hmac对象。因为它是流式数据,所以可以使用新数据调用多次。
计算传入数据的hmac值。encoding
可以是'hex'
、'binary'
或'base64'
,如果没有指定encoding
,将返回buffer。
注意:调用digest()
后不能再用hmac
对象。
使用传入的算法和秘钥来生成并返回加密对象。
algorithm
取决于openssl,例如'aes192'
等。最近发布的版本中,openssl list-cipher-algorithms
将会展示可用的加密算法。password
用来派生key 和iv,它必须是一个'binary'
编码的字符串或者一个buffer。
它是可读写的stream流。写入的数据来用计算hmac。当写入流结束后,使用read()
方法来获取计算后的值。也支持老的update
和digest
方法。
注意,openssl函数evp_bytestokey摘要算法如果是一次迭代(one iteration),无需盐值(no salt)的md5时,createcipher
为它派生秘钥。缺少盐值使得字典攻击,相同的密码总是生成相同的key,低迭代次数和非加密的哈希算法,使得密码测试非常迅速。
openssl推荐使用pbkdf2来替换evp_bytestokey,推荐使用crypto.pbkdf2来派生key和iv ,推荐使用createcipheriv()来创建加密流。
创建并返回一个加密对象,用指定的算法,key和iv。
algorithm
参数和createcipher()
一致。key
在算法中用到。iv
是一个initialization vector.
key
和iv
必须是'binary'
的编码字符串或buffers.
加密数据的类。.
通过crypto.createcipher
和crypto.createcipheriv
返回。
它是可读写的stream流。写入的数据来用计算hmac。当写入流结束后,使用read()
方法来获取计算后的值。也支持旧的update
和digest
方法。
根据data
来更新哈希内容,编码方式根据input_encoding
来定,有'utf8'
、'ascii'
或者'binary'
。如果没有传入值,默认编码方式是'binary'
。如果data
是buffer
,input_encoding
将会被忽略。
output_encoding
指定了输出的加密数据的编码格式,它可用是'binary'
、'base64'
或'hex'
。如果没有提供编码,将返回buffer。
返回加密后的内容,因为它是流式数据,所以可以使用不同的数据调用很多次。
返回加密后的内容,编码方式是由output_encoding
指定,可以是'binary'
、'base64'
或'hex'
。如果没有传入值,将返回buffer。
注意:cipher
对象不能在final()
方法之后调用。
你可以禁用输入数据自动填充到块大小的功能。如果auto_padding
是false, 那么输入数据的长度必须是加密器块大小的整倍数,否则final
会失败。这对非标准的填充很有用,例如使用0x0而不是pkcs的填充。这个函数必须在cipher.final
之前调用。
加密认证模式(目前支持:gcm),这个方法返回经过计算的认证标志buffer
。必须使用final
方法完全加密后调用。
加密认证模式(目前支持:gcm),这个方法设置附加认证数据( aad )。
根据传入的算法和密钥,创建并返回一个解密对象。这是createcipher()的镜像。
根据传入的算法,密钥和iv,创建并返回一个解密对象。这是createcipheriv()的镜像。
解密数据类。
通过crypto.createdecipher
和crypto.createdecipheriv
返回。
解密对象是可读写的streams流。用写入的加密数据生成可读的纯文本数据。也支持老的update
和digest
方法。
使用参数data
更新需要解密的内容,其编码方式是'binary'
、'base64'
或'hex'
。如果没有指定编码方式,则把data
当成buffer
对象。
如果data
是buffer
,则忽略input_encoding
参数。
参数output_decoding
指定返回文本的格式,是'binary'
、'ascii'
或'utf8'
之一。如果没有提供编码格式,则返回buffer。
返回剩余的解密过的内容,参数output_encoding
是'binary'
、'ascii'
或'utf8'
,如果没有指定编码方式,返回buffer。
注意:decipher
对象不能在final()
方法之后使用。
如果加密的数据是非标准块,可以禁止其自动填充,防止decipher.final
检查并移除。仅在输入数据长度是加密块长度的整数倍的时才有效。你必须在 decipher.update
前调用。
对于加密认证模式(目前支持:gcm),必须用这个方法来传递接收到的认证标志。如果没有提供标志,或者密文被篡改,将会抛出final
标志,认证失败,密文会被抛弃。
对于加密认证模式(目前支持:gcm),用这个方法设置附加认证数据( aad )。
根据传入的算法创建并返回一个签名数据。 openssl的最近版本里,openssl list-public-key-algorithms
会列出所有算法,比如'rsa-sha256'
。
生成数字签名的类。
通过crypto.createsign
返回。
签名对象是可读写的streams流。可写数据用来生成签名。当所有的数据写完,sign
签名方法会返回签名。也支持老的update
和digest
方法。
用参数data
来更新签名对象。因为是流式数据,它可以被多次调用。
根据传送给sign的数据来计算电子签名。
private_key
可以是一个对象或者字符串。如果是字符串,将会被当做没有密码的key。
private_key
:
key
: 包含 pem 编码的私钥passphrase
: 私钥的密码返回值output_format
包含数字签名, 格式是'binary'
、'hex'
或'base64'
之一。如果没有指定encoding
,将返回buffer。
注意:sign
对象不能在sign()
方法之后调用。
根据传入的算法,创建并返回验证对象。是签名对象(signing object)的镜像。
用来验证签名的类。
通过crypto.createverify
返回。
是可写streams流。可写数据用来验证签名。一旦所有数据写完后,如签名正确verify
方法会返回true
。
也支持老的update
方法。
用参数data
来更新验证对象。因为是流式数据,它可以被多次调用。
使用object
和signature
验证签名数据。参数object
是包含了pem编码对象的字符串,它可以是rsa公钥,dsa公钥,或x.509证书。signature
是之前计算出来的数字签名。signature_format
可以是'binary'
、'hex'
或'base64'
之一,如果没有指定编码方式 ,则默认是buffer对象。
根据数据和公钥验证签名有效性,来返回true或false。
注意:verifier
对象不能在verify()
方法之后调用。
创建一个diffie-hellman密钥交换(diffie-hellman key exchange)对象,并根据给定的位长度生成一个质数。如果没有指定参数generator
,默认为2
。
使用传入的prime
和generator
创建diffie-hellman秘钥交互对象。
generator
可以是数字,字符串或buffer。
如果没有指定generator
,使用2
.
prime_encoding
和generator_encoding
可以是'binary'
、'hex'
或'base64'
。
如果没有指定prime_encoding
, 则buffer为prime
。
如果没有指定generator_encoding
,则buffer为generator
。
创建diffie-hellman秘钥交换的类。
通过crypto.creatediffiehellman
返回。
在初始化的时候,如果有警告或错误,将会反应到这。它是以下值(定义在constants
模块):
dh_check_p_not_safe_prime
dh_check_p_not_prime
dh_unable_to_check_generator
dh_not_suitable_generator
生成秘钥和公钥,并返回指定格式的公钥。这个值必须传给其他部分。编码方式:'binary'
、'hex'
或'base64'
。如果没有指定编码方式,将返回buffer。
使用other_public_key
作为第三方公钥来计算并返回共享秘密(shared secret)。秘钥用input_encoding
编码。编码方式为:'binary'
、'hex'
或 'base64'
。如果没有指定编码方式 ,默认为buffer。
如果没有指定返回编码方式,将返回buffer。
用参数encoding指明的编码方式返回diffie-hellman质数,编码方式为: 'binary'
、'hex'
或'base64'
。如果没有指定编码方式,将返回buffer。
用参数encoding指明的编码方式返回diffie-hellman生成器,编码方式为: 'binary'
、'hex'
或'base64'
。如果没有指定编码方式 ,将返回buffer。
用参数encoding指明的编码方式返回diffie-hellman公钥,编码方式为: 'binary'
、'hex'
, 或'base64'
。如果没有指定编码方式 ,将返回buffer。
用参数encoding指明的编码方式返回diffie-hellman私钥,编码方式为: 'binary'
、'hex'
或'base64'
。如果没有指定编码方式 ,将返回buffer。
设置diffie-hellman的公钥,编码方式为: 'binary'
、'hex'
或'base64'
,如果没有指定编码方式 ,默认为buffer。
设置diffie-hellman的私钥,编码方式为: 'binary'
、'hex'
或'base64'
,如果没有指定编码方式 ,默认为buffer。
创建一个预定义的diffie-hellman秘钥交换对象。支持的组: 'modp1'
、'modp2'
、'modp5'
(定义于rfc 2412),并且'modp14'
、'modp15'
、'modp16'
、'modp17'
、'modp18'
(定义于rfc 3526)。返回对象模仿了上述创建的crypto.creatediffiehellman()对象,但是不允许修改秘钥交换(例如,diffiehellman.setpublickey())。使用这套流程的好处是,双方不需要生成或交换组组余数,节省了计算和通讯时间。
例如 (获取一个共享秘密):
var crypto = require('crypto');
var alice = crypto.getdiffiehellman('modp5');
var bob = crypto.getdiffiehellman('modp5');
alice.generatekeys();
bob.generatekeys();
var alice_secret = alice.computesecret(bob.getpublickey(), null, 'hex');
var bob_secret = bob.computesecret(alice.getpublickey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
使用传入的参数curve_name
,创建一个elliptic curve (ec) diffie-hellman秘钥交换对象。
这个类用来创建ec diffie-hellman秘钥交换。
通过crypto.createecdh
返回。
生成ec diffie-hellman的秘钥和公钥,并返回指定格式和编码的公钥,它会传递给第三方。
参数format
是'compressed'
、 'uncompressed'
或 'hybrid'
。如果没有指定,将返回'uncompressed'
格式.
参数encoding
是'binary'
、'hex'
或'base64'
。如果没有指定编码方式,将返回buffer。
以other_public_key
作为第三方公钥计算共享秘密,并返回。秘钥会以input_encoding
来解读。编码是:'binary'
、'hex'
或'base64'
。如果没有指定编码方式,默认为buffer。
如果没有指定编码方式,将返回buffer。
用参数encoding指明的编码方式返回ec diffie-hellman公钥,编码方式为: 'compressed'
、'uncompressed'
或'hybrid'
。如果没有指定编码方式 ,将返回'uncompressed'
。
编码是:'binary'
、'hex'
或'base64'
。如果没有指定编码方式 ,默认为buffer。
用参数encoding指明的编码方式返回ec diffie-hellman私钥,编码是:'binary'
、'hex'
或'base64'
。如果没有指定编码方式 ,默认为buffer。
设置ec diffie-hellman的公钥,编码方式为: 'binary'
、'hex'
或'base64'
,如果没有指定编码方式,默认为buffer。
设置ec diffie-hellman的私钥,编码方式为: 'binary'
、'hex'
或'base64'
,如果没有指定编码方式,默认为buffer。
例如 (包含一个共享秘密):
var crypto = require('crypto');
var alice = crypto.createecdh('secp256k1');
var bob = crypto.createecdh('secp256k1');
alice.generatekeys();
bob.generatekeys();
var alice_secret = alice.computesecret(bob.getpublickey(), null, 'hex');
var bob_secret = bob.computesecret(alice.getpublickey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
异步pbkdf2提供了一个伪随机函数hmac-sha1,根据给定密码的长度,salt和iterations来得出一个密钥。回调函数得到两个参数 (err, derivedkey)。
例如:
crypto.pbkdf2('secret', 'salt', 4096, 512, 'sha256', function(err, key) {
if (err)
throw err;
console.log(key.tostring('hex')); // 'c5e478d...1469e50'
});
在crypto.gethashes()里有支持的摘要函数列表。
异步pbkdf2函数, 返回derivedkey或抛出错误。
生成一个密码强度随机的数据:
// async
crypto.randombytes(256, function(ex, buf) {
if (ex) throw ex;
console.log('have %d bytes of random data: %s', buf.length, buf);
});
// sync
try {
var buf = crypto.randombytes(256);
console.log('have %d bytes of random data: %s', buf.length, buf);
} catch (ex) {
// handle error
// most likely, entropy sources are drained
}
注意:如果没有足够积累的熵来生成随机强度的密码,将会抛出错误,或调用回调函数返回错误。换句话说,没有回调函数的crypto.randombytes
不会阻塞,即使耗尽所有的熵。
生成非密码学强度的伪随机数据。如果数据足够长会返回一个唯一数据,但是这个数可能是可以预期的。因此,当不可预期很重要的时候,不要用这个函数。例如,在生成加密的秘钥时。
用法和crypto.randombytes
相同。
这个类和签过名的公钥打交道。最重要的场景是处理<keygen>
元素,http://www.openssl.org/docs/apps/spkac.html。
通过crypto.certificate
返回.
根据spkac返回true或false。
根据提供的spkac,返回加密的公钥。
输出和spkac关联的编码challenge。
使用public_key
加密buffer
。目前仅支持rsa。
public_key
可以是对象或字符串。如果public_key
是一个字符串,将会当做没有密码的key,并会用rsa_pkcs1_oaep_padding
。
public_key
:
key
: 包含有pem编码的私钥。padding
: 填充值,如下constants.rsa_no_padding
constants.rsa_pkcs1_padding
constants.rsa_pkcs1_oaep_padding
注意:所有的填充值定义在constants
模块.
使用private_key
来解密buffer
.
private_key
:
key
: 包含有 pem 编码的私钥passphrase
: 私钥的密码padding
: 填充值,如下:constants.rsa_no_padding
constants.rsa_pkcs1_padding
constants.rsa_pkcs1_oaep_padding
注意:所有的填充值定义于constants
模块.
函数所用的编码方式可以是字符串或buffer ,默认值是'buffer'。这是为了加密模块兼容默认'binary'为编码方式的遗留程序。
注意:新程序希望用buffer对象,所以这是暂时手段。
在统一的流api概念出现前,在引入buffer对象来处理二进制数据之前,crypto模块就已经添加到node。
因此,流相关的类里没有其他的node类里的典型方法,并且很多方法接收并返回二级制编码的字符串,而不是buffers。在最近的版本中,这些函数改成默认使用 buffers。
对于一些场景来说这是重大变化。
例如,如果你使用默认参数给签名类,将结果返回给认证类,中间没有验证数据,程序会正常工作。之前你会得到二进制编码的字符串,并传递给验证类,现在则是 buffer。
如果你之前使用的字符串数据在buffers对象不能正常工作(比如,连接数据,并存储在数据库里 )。或者你传递了二进制字符串给加密函数,但是没有指定编码方式,现在就需要提供编码参数。如果想切换回原来的风格,将crypto.default_encoding
设置为'binary'。注意,新的程序希望是buffers,所以之前的方法只能作为临时的办法。