文章来源:互联网整理作者:招财猫手游网发布时间:2023-10-26 14:29:40
2015小明发布台湾加密相关介绍,Crypto模块的目的是提供常用的加密和散列算法。用纯JavaScript代码实现这些功能不是不可能的,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaS
Crypto模块的目的是提供常用的加密和散列算法。用纯JavaScript代码实现这些功能不是不可能的,但速度会非常慢。
Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。MD5和SHA1
MD5是一种常用的哈希算法,用于给任意数据一个“签名”。这个签名通常用一个十六进制的字符串表示:
const crypto = require('crypto');const hash = cry('md5');// 可任意多次调用update():('Hello, world!');('Hello, nodejs!');con('hex')); // 7e1977739c748beac0c0fd14fd26a544
update()方法默认字符串编码为UTF-8,也可以传入Buffer。
如果要计算SHA1,只需要把'md5'改成'sha1',就可以得到SHA1的结果1f32b9c9932c02227819a4151feed43e131aca40。
还可以使用更安全的sha256和sha512。
Hmac
Hmac算法也是一种哈希算法,它可以利用MD5或SHA1等哈希算法。不同的是,Hmac还需要一个密钥:
const crypto = require('crypto');const hmac = cry('sha256', 'secret-key');('Hello, world!');('Hello, nodejs!');con('hex')); // 80f7e22570...
只要密钥发生了变化,那么同样的输入数据也会得到不同的WwW+.mUWUyA.coM签名,因此,可以把Hmac理解为用随机数“增强”的哈希算法。
AES
AES是一种常用的对称加密算法,加解密都用同一个密钥。crypto模块提供了AES支持,但是需要自己封装好函数,便于使用:
const crypto = require('crypto');function aesEncrypt(data, key) { const cipher = cry('aes192', key); var crypted = ci(data, 'utf8', 'hex'); crypted += ci('hex'); return crypted;}function aesDecrypt(encrypted, key) { const decipher = cry('aes192', key); var decrypted = deci(encrypted, 'hex', 'utf8'); decrypted += deci('utf8'); return decrypted;}var data = 'Hello, this is a secret message!';var key = 'Password!';var encrypted = aesEncrypt(data, key);var decrypted = aesDecrypt(encrypted, key);con('Plain text: ' + data);con('Encrypted text: ' + encrypted);con('Decrypted text: ' + decrypted);
运行结果如下:
Plain text: Hello, this is a secret message!Encrypted text: 8a944d97bdabc157a5b7a40cb180e7...Decrypted text: 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格式。
Diffie-Hellman
DH算法是一种密钥交换协议,它可以让双方在不泄漏密钥的情况下协商出一个密钥来。DH算法基于数学原理,比如小明和小红想要协商一个密钥,可以这么做:
在这个过程中,密钥2并不是小明告诉小红的,也不是小红告诉小明的,而是双方协商计算出来的。第三方只能知道p=23,g=5,A=8,B=19,由于不知道双方选的秘密整数a=6和b=15,因此无法计算出密钥2。
用crypto模块实现DH算法如下:
const crypto = require('crypto');// xiaoming's keys:var ming = cry(512);var ming_keys = ming.generateKeys();var prime = ming.getPrime();var generator = ming.getGenerator();con('Prime: ' + ('hex'));con('Generator: ' + genera('hex'));// xiaohong's keys:var hong = cry(prime, generator);var hong_keys = ();// exchange and generate secret:var ming_secret = ming.computeSecret(hong_keys);var hong_secret = (ming_keys);// print secret:con('Secret of Xiao Ming: ' + ming_('hex'));con('Secret of Xiao Hong: ' + hong_('hex'));
运行后,可以得到如下输出:
$ node dh.js Prime: a8224c...deead3Generator: 02Secret of Xiao Ming: 695308...d519beSecret of Xiao Hong: 695308...d519be
注意每次输出都不一样,因为素数的选择是随机的。
RSA
RSA算法是一种非对称加密算法,即由一个私钥和一个公钥构成的密钥对,通过私钥加密,公钥解密,或者通过公钥加密,私钥解密。其中,公钥可以公开,私钥必须保密。
RSA算法是1977年由Ron Rivest、Adi Shamir和Leonard Adleman共同提出的,所以以他们三人的姓氏的头字母命名。
当小明给小红发送信息时,可以用小明自己的私钥加密,小红用小明的公钥解密,也可以用小红的公钥加密,小红用她自己的私钥解密,这就是非对称加密。相比对称加密,非对称加密只需要每个人各自持有自己的私钥,同时公开自己的公钥,不需要像AES那样由两个人共享同一个密钥。
在使用Node进行RSA加密前,我们先要准备好私钥和公钥。
首先,在命令行执行以下命令以生成一个RSA密钥对:
openssl genrsa -aes256 -out r 2048
根据提示输入密码,这个密码是用来加密RSA密钥的,加密方式指定为AES256,生成的RSA的密钥长度是2048位。执行成功后,我们获得了加密的r文件。
第二步,通过上面的r加密文件,我们可以导出原始的私钥,命令如下:
openssl rsa -in r -outform PEM -out r
输入第一步的密码,我们获得了解密后的私钥。
类似的,我们用下面的命令导出原始的公钥:
openssl rsa -in r -outform PEM -pubout -out r
这样,我们就准备好了原始私钥文件r和原始公钥文件r,编码格式均为PEM。
下面,使用crypto模块提供的方法,即可实现非对称加解密。
首先,我们用私钥加密,公钥解密:
const fs = require('fs'), crypto = require('crypto');// 从文件加载key:function loadKey(file) { // key实际上就是PEM编码的字符串: return (file, 'utf8');}let prvKey = loadKey('./r'), pubKey = loadKey('./r'), message = 'Hello, world!';// 使用私钥加密:let enc_by_prv = cry(prvKey, Bu(message, 'utf8'));con('encrypted by private key: ' + enc_by_('hex'));let dec_by_pub = cry(pubKey, enc_by_prv);con('decrypted by public key: ' + dec_by_('utf8'));
执行后,可以得到解密后的消息,与原始消息相同。
接下来我们使用公钥加密,私钥解密:
// 使用公钥加密:let enc_by_pub = cry(pubKey, Bu(message, 'utf8'));con('encrypted by public key: ' + enc_by_('hex'));// 使用私钥解密:let dec_by_prv = cry(prvKey, enc_by_pub);con('decrypted by private key: ' + dec_by_('utf8'));
执行得到的解密后的消息仍与原始消息相同。
如果我们把message字符串的长度增加到很长,例如1M,这时,执行RSA加密会得到一个类似这样的错误:data too large for key size,这是因为RSA加密的原始信息必须小于Key的长度。那如何用RSA加密一个很长的消息呢?实际上,RSA并不适合加密大数据,而是先生成一个随机的AES密码,用AES加密原始信息,然后用RSA加密AES口令,这样,实际使用RSA时,给对方传的密文分两部分,一部分是AES加密的密文,另一部分是RSA加密的AES口令。对方用RSA先解密出AES口令,再用AES解密密文,即可获得明文。
证书
crypto模块也可以处理数字证书。数字证书通常用在SSL连接,也就是Web的https连接。一般情况下,https连接只需要处理服务器端的单向认证,如无特殊需求(例如自己作为Root给客户发认证证书),建议用反向代理服务器如Nginx等Web服务器去处理证书。
相关攻略 更多
最新资讯 更多
原神浮生石片有什么用
更新时间:2022-08-22
原神可莉要元素精通吗(原神可莉武器推荐)
更新时间:2022-08-22
奥拉星潮牌盲盒机在哪(银潮牌活塞式空压机)
更新时间:2022-08-22
帝王上阵有讲究?这是《空岛幻想》的布阵指南~
更新时间:2022-08-22
原神赛诺是男是女 新角色性别介绍
更新时间:2022-08-22
原神四风原典适合谁带 是谁的专属武器
更新时间:2022-08-22
王者荣耀snk英雄哪个值得入手 SNK英雄强度排行
更新时间:2022-08-22
封龙战纪好玩吗?最新游戏评测解析(封龙战纪攻略)
更新时间:2022-08-22
和平精英在哪里练枪(和平精英在哪里练枪最快)
更新时间:2022-08-22
云顶之弈巨岩龙羁绊效果是什么 云顶之弈S7.5新羁绊巨岩龙效果介绍
更新时间:2022-08-26