在常用的nodejs+express工程中,为了安全在登录及表单传输时,应该都需进行加密传输,目前个人常用到的加密方式有下列几种:
1、Hash算法加密:
创建一个nodejs文件hash.js,输入内容如下:
var crypto = require('crypto'); //加载crypto库
console.log(crypto.getHashes()); //打印支持的hash算法
结果如下:
[ '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' ]
在nodejs中使用:(createHash('md5')中的‘md5’可以换成袭击需要的hash加密方法)
var content = 'password';//加密的明文;
var md5 = crypto.createHash('md5');//定义加密方式:md5不可逆,此处的md5可以换成任意hash加密的方法名称;
md5.update(content);
var d = md5.digest('hex'); //加密后的值d
console.log("加密的结果:"+d);
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC可以有效防止一些类似md5的彩虹表等攻击,比如一些常见的密码直接MD5存入数据库的,可能被反向破解。
定义HMAC需要一个加密用散列函数(表示为H,可以是MD5或者SHA-1)和一个密钥K。我们用B来表示数据块的字节数。(以上所提到的散列函数的分割数据块字长B=64),用L来表示散列函数的输出数据字节数(MD5中L=16,SHA-1中L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。一般情况下,推荐的最小密钥K长度是L个字节。
下面为我在项目中使用到的Hmac加密(采用sha1方式):(由于密钥会通过随机生成的16位数进行加密后再对明文加密,每次生成的新密钥(token)都不同,所以最后生成的密文也不会相同,这种加密不可逆,
即使为md5方式,也难以通过彩虹表来攻击)
/********hmac-sha1加密***************/
var content = 'password';//加密的明文;
var token1='miyue';//加密的密钥;
var buf = crypto.randomBytes(16);
token1 = buf.toString('hex');//密钥加密;
console.log("生成的token(用于加密的密钥):"+token1);
var SecrectKey=token1;//秘钥;
var Signture = crypto.createHmac('sha1', SecrectKey);//定义加密方式
Signture.update(content);
var miwen=Signture.digest().toString('base64');//生成的密文后将再次作为明文再通过pbkdf2算法迭代加密;
console.log("加密的结果f:"+miwen); /**********对应的结果(每次生成的结果都不一样)******************/
生成的token(用于加密的密钥):de7c3dafede518a1ad9c2096ee9b4eff
加密的结果f:PUX7fnOMlqVj+BS9o6RnNgxfffY=
生成的token(用于加密的密钥):93fee046ebf47412c2d54c1e808218d2
加密的结果f:/ERkUcrjkwxzgxNM7WczU8RaX5o=
3、对称加密和非对称加密:
- 对称加密算法的原理很容易理解,通信一方用KEK加密明文,另一方收到之后用同样的KEY来解密就可以得到明文。
- 不对称加密算法,使用两把完全不同但又是完全匹配的一对Key:公钥和私钥。在使用不对称加密算法加密文件时,只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。
3.1:对称加密:
创建一个nodejs文件cipher.js,输入内容如下:
var crypto = require('crypto'); //加载crypto库
console.log(crypto.getCiphers()); //打印支持的cipher算法
[ 'CAST-cbc',
'aes-128-cbc',
'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-cfb',
'aes-192-cfb1',
'aes-192-cfb8',
'aes-192-ctr',
'aes-192-ecb',
'aes-192-gcm',
'aes-192-ofb',
'aes-256-cbc',
'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-GCM',
'id-aes192-GCM',
'id-aes256-GCM',
'idea',
'idea-cbc',
'idea-cfb',
'idea-ecb',
'idea-ofb',
'rc2',
'rc2-40-cbc',
'rc2-64-cbc',
'rc2-cbc',
'rc2-cfb',
'rc2-ecb',
'rc2-ofb',
'rc4',
'rc4-40',
'rc4-hmac-md5',
'seed',
'seed-cbc',
'seed-cfb',
'seed-ecb',
'seed-ofb' ]
下面是我在项目中用到的对称加密算法:
//在app.js中配置路由
...
var jiami=require("./routes/jiami");
....
app.use("/jiami",jiami);
在service中请求node端路由:
1 $http.post("/app/jiami/encrypt",{str:JSON.stringify(user)}).success(function(miwen){
// console.log("返回的密文:"+miwen);
}).error(function(error){
return deferred.reject(error);
});
var secret='pass';//密钥 //加密
router.post("/encrypt",function(req,res){
var str=req.body.str;//明文
var cipher = crypto.createCipher('aes192', secret);
var enc = cipher.update(str, 'utf8', 'hex');//编码方式从utf-8转为hex;
enc += cipher.final('hex');//编码方式从转为hex;
res.send(enc);
});
//解密
router.post("/decrypt",function(req,res){
var str=req.body.str;//明文
var decipher = crypto.createDecipher('aes192', secret);
var dec = decipher.update(str, 'hex', 'utf8');//编码方式从hex转为utf-8;
dec += decipher.final('utf8');//编码方式从utf-8;
res.send(dec);
});
jiami.js
3.2、非对称加密:这种方法还没用到,待后面继续补充。