加密这方面nodejs自带原生的crypto模块,在网关开发中或多或少会牵涉到这块,大部分集中在des-ecb
、aes
的加密上,所以咱们封装了这么一个工具库用来平时的加密和解密使用,传送门。html
在使用这些api以前,咱们来熟悉熟悉一下crypto模块,以及了解加密和解密的一些基本知识。node
nodejs提供了众多和加密解密相关的封装器,好比OpenSSL的hash、HMAC(哈希信息验证码)、cipher(加密)、decipher(解密)、sign(签名)和校验函数。如今咱们简单地学习一下这些对应的概念。git
所谓的SPKAC是由网景公司原始实现的一种CSR(Certificate Signing Request/证书注册请求)机制。crypto模块提供Certificate
类来处理SPKAC数据。Nodejs内部使用的是OpenSSL's SPKAC实现方式。github
Cipher
类实例用来加密数据。使用方式以下两种,任选其一便可:算法
cipher.update
和cipher.final
方法来产生加密的数据所谓的Cipher是加密的意思,天然就有加密的算法了,自己密码学就是一门复杂的学科,这里咱们只会挑选几个比较经常使用的加密算法来简单解释。typescript
首先咱们能够查看nodejs支持的加密算法有哪些?由于nodejs内部是有使用到openssl,因此也能够经过电脑自带的openssl命令openssl list-cipher-algorithms
获取,也可使用下面的方式获取:api
const crypto = require('crypto')
crypto.getCiphers()
复制代码
获得一个比较大的数组,都列举不完了:数组
[ 'aes-128-cbc',
'aes-128-cbc-hmac-sha1',
'aes-128-cbc-hmac-sha256',
'aes-128-ccm',
'aes-128-cfb',
'aes-128-cfb1',
'aes-128-cfb8',
'aes-128-ctr',
'aes-128-ecb',
'aes-128-gcm',
'aes-128-ocb',
'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-ocb',
'aes-192-ofb',
'aes-256-cbc',
'aes-256-cbc-hmac-sha1',
'aes-256-cbc-hmac-sha256',
'aes-256-ccm',
'aes-256-cfb',
'aes-256-cfb1',
'aes-256-cfb8',
'aes-256-ctr',
'aes-256-ecb',
'aes-256-gcm',
'aes-256-ocb',
'aes-256-ofb',
'aes-256-xts',
'aes128',
'aes128-wrap',
'aes192',
'aes192-wrap',
'aes256',
'aes256-wrap',
'bf',
'bf-cbc',
'bf-cfb',
'bf-ecb',
'bf-ofb',
'blowfish',
...
'des',
'des-cbc',
'des-cfb',
'des-cfb1',
'des-cfb8',
'des-ecb',
...
'des3',
... 39 more items ]
复制代码
咱们挑选AES加密算法和DES加密算法来讲说几个基本的加密概念安全
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。通过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。bash
AES使用的秘钥长度能够128位、192位或256位,因此你看到的加密算法:aes-128/196/256,表示的都是秘钥的位数。而最后的一段是AES的工做模式,最经常使用的工做模式是ECB、CBC、CFB和OFB四种。
des对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是一样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一种对称加密算法。
DES使用一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。因此正常咱们给DES加密的时候都是传递56位秘钥便可。一样DES也有几种工做模式:DES、ECB、CBC,工做模式基本和上面的一致。
nodejs使用crypto.createCipheriv()
来建立加密实例,该函数的接受三个参数:algorithm、key、initialization vector(iv)。
那么问题来了,什么是初始化向量?何时须要使用到?
根据wiki的解释:
在密码学中,初始化向量(IV)或者起始变量(SV)是一段固定大小的到密码原语的输入,该原语一般要求是随机或伪随机的。随机化对于加密方案实现语义安全性相当重要,这种特性使得在相同密钥下重复使用该方案不容许攻击者推断加密消息片断之间的关系。对于分组密码,IV的使用由操做模式来描述。其余原语也须要随机化,例如通用哈希函数和基于此的消息身份验证代码。
复制代码
一句话归纳就是:为了保证每条消息的惟一性,须要使用初始化向量IV。
在上述的四种工做模式中,除了ECB不须要用到初始化向量,其余三种都须要用到IV。咱们可使用该方法生成IV: Crypto.randomBytes(16)
建立加密实例后,有可能会用到这个方法:setAutoPadding
,那么为何咱们会须要padding呢?
首先咱们先了解该方法的做用:当使用块加密算法的时候,Cipher类会自动地添加padding到输入块中达到合适的块大小。当咱们调用该函数禁用掉这个的时候,整个输入块的长度必须为cipher块尺寸的整数倍,不然调用cipher.final的时候是会报错的。
接着回答刚才的问题:
因为被加密数据分组时,有可能不会正好为128bit的整数倍,因此须要padding(填充补齐),填充的模式有如下几种:
这里还有一个问题是:Nodejs如何决定咱们的padding使用的是哪一种呢?这个问题待解!
另一个问题是,调用完cipher.update
以后还得调用一个cipher.final
,这是为啥呢?由于final的做用是收尾,由于update以后会有一些剩余没有加密的数据,只有调用了这个才算是对整个数据源进行加密,所以咱们看到代码都是两者的结果的一个拼接。
Decipher类的实例用于解密数据。和Cipher同样的使用方法。就再也不赘述了
DiffieHellman类是一个用来建立Diffie-Hellman键交换的工具。什么叫作Diffie-Hellman?Diffie-Hellman算法是第一个公开密钥算法,早在 1976 年就发现了。其安全性源于在有限域上计算离散对数,比计算指数更为困难。该算法可使两个用户之间安全地交换一个密钥,但不能用于加密或解密信息。具体实现原理不赘述。
ECDH类是建立椭圆曲线Diffie-Hellman(Elliptic Curve Diffie-Hellman (ECDH))键交换的实用工具。ECDH是基于ECC(Elliptic Curve Cryptosystems,椭圆曲线密码体制,参看ECC)的DH( Diffie-Hellman)密钥交换算法。交换双方能够在不共享任何秘密的状况下协商出一个密钥。
ECC是创建在基于椭圆曲线的离散对数问题上的密码体制,给定椭圆曲线上的一个点P,一个整数k,求解Q=kP很容易;给定一个点P、Q,知道Q=kP,求整数k确是一个难题。ECDH即创建在此数学难题之上。
Hash类是用于建立数据哈希值的工具类。使用方式以下两种,任选其一便可:
hash.update
和hash.final
方法来产生加密的数据Hmac类是用于建立加密Hmac摘要的工具。HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要做为输出。
Sign类是用于生成签名的实用工具。使用方式以下两种,任选其一便可:
sign.update
和sign.sign
方法来产生加密的数据Verify类是验证签名的工具。使用方式以下两种,任选其一便可:
verify.update
和verify.verify
的方法来验证签名基于上面的一些基本知识,咱们在Nodejs的基础上封装了这么一个基本的工具库,供平时咱们开始中使用,鉴于还有好多在平时中没有用到,这里先提供简单的一些封装,等后续有用到的时候在上面继续完善。
整个工具库根据crypto的功能分为如下文件:
├── test 单元测试文件
├── types typescript类型文件
├── lib
│ ├── cipher 封装了加密解密相关的方法类
│ ├── certificate 封装了证书相关的方法类
│ ├── diffieHellman 封装了Diffie-Hellman相关的方法类
│ ├── ecdh 封装了椭圆曲线Diffie-Hellman相关的方法类
│ ├── hash 封装了哈希相关的方法类
│ ├── hmac 封装了Hmac摘要相关的方法类
│ ├── sign 封装了签名相关的方法类
│ └── verify 封装了签名验证相关的方法类
复制代码
后续慢慢完善这个工具库。传送门