手机版

节点中的密码安全性(加密)

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

本文将解释在前端注册或登录项目时,如何确保用户密码安全地传输到服务器并最终存储在数据库中,前端和后端是分开的

为什么需要加密

加密真的有必要吗?

让我们看看如果在前端发起的ajax请求中密码没有加密会发生什么。

F12打开chrome开发工具,找到请求,并检查请求参数,如下所示:

如果你的协议是http,那么从前端到后端的密码几乎是裸奔,因为http传输的是明文,在传输过程中很可能被窃听、伪装或者篡改。

那么,我们就不能只得到https吗?

Https可以大大增加网站的安全性,但是在使用https之前必须购买证书(也有免费的证书)。对于个人网站或当您不想获得证书时,您必须至少加密用户密码。

流程图

首先,看一下总流程图。首先,我们使用工具生成公钥和私钥,并将它们放在服务器中。前端发起获取公钥的请求,获取公钥后对密码进行加密,然后将加密后的密码发送给服务器,由服务器用密钥解密,最后用sha1对密码进行加密并存储在数据库中。

生成RSA公钥和密钥

既然选择了RSA加密,我们首先要有工具。openssl是一个常见的,但这里不介绍。如果有兴趣,请自行参考。对于node,我将介绍一个很好的库Node-RSA,我们将使用它来生成RSA公钥和密钥。

RSA是一种非对称加密算法,即由一个密钥和一个公钥组成的密钥对,用公钥加密解密或用公钥加密解密。其中,公钥可以公开,私钥必须保密。

节点-RSA生成的公钥和密钥码如下:

const NodeRSA=require(' node-RSA ')const fs=require(' fs ')//生成新的512位长度的key Var key=new NodeRSA({ b : 512 })key . setoptions({ encryptionscheme 3360 ' pkcs1 ' })Var private PEM=key . export key(' pkcs1-private-PEM ')Var public der=key . export key(' pkcs8-public-der ')Var public der str=public der。tostring(' base64 ')//保存返回前端的公钥fs.writefile('。/PEM/public.pem ',publicderstr,(err)={ if(err)throernconsole . log('公钥已保存!')})//保存私钥fs.writefile('。/PEM/private.pem ',private PEM,(err)={ if(err)throw err console . log('私钥已保存!')})执行完成后,我们会得到根目录下的公钥和私钥文件:

注意:服务器端的公钥和密钥应该定期更改,例如,每次服务器重新启动时。

前端加密

核心代码如下:

脚本src=' http :https://cdn . bootscs.com/jsencrypt/2 . 3 . 1/jsencrypt . min . js '/脚本脚本src=' http :https://cdn . bootscs.com/axios/0 . 18 . 0/axios . min . js '/脚本函数reg() { axios({ method: 'post ',Url :' http://127.0.0然后(RES={let result=从后端获得的res.data//the公钥String var publicPem=result //用JSEncrypt var Encrypt=new js Encrypt()加密密码。设置公钥(public PEM)var password=' ABC 123 ' password=encrypt。加密(密码)axios({ method: 'post ',URL : ' http://127 . 0 . 0 . 1:3000/reg ',Data: { password : password } })。然后(RES={ let result=RES . dataconsole . log(result)})。catch(错误={ console . log(error)})})}/脚本前端将使用jsencrypt对其进行加密。详细用法请参考github。

后端解密

后端核心代码:

const express=require(' express ');const crypto=require(' crypto ');const fs=require(' fs ');var privatePem=fs.readFileSync(' ./PEM/private。PEM ';var app=express();app。使用(快递。JSON());//CORS注意:要放在处理路由前函数跨域(请求、res、下一个){ RES . header('访问控制-允许-源',' * ');res.header('访问控制-允许-头','内容类型');next();} app。使用(跨域)应用程序。使用(函数(req,res,next) { //不加会报错如果(请求。method==' OPTIONS '){ RES . end(' ok ')return }开关(req。URL){大小写'/GetPublicKey ' :让publicPem=fs.readFileSync(' ./pem/public.pem ',' utf-8 ')RES . JSON(public PEM)break case '/reg ' ://解密var privateKey=fs.readFileSync(' ./pem/private.pem ',' utf8 ')var password=req。尸体。密码var缓冲区2=缓冲区。from(password,' base64 ')var decrypt=crypto。私钥解密({ key :私钥,padd :加密。常数。RSA _ PKCS1 _ PADDING//注意这里的常量值要设置为RSA_PKCS1_PADDING },buffer2)控制台. log(已解密。tostring(' utf8 ')//sha1加密var sha1=加密。创建哈希(' sha1 ');var password=sha1.update(已解密)。摘要(' hex ');console.log('输入到数据库中的密码是: ',密码)//存入数据库中//存储到数据库.RES . end(' reg ok ')break } })应用程序。听(3000,' 127.0.0.1 ')这里,我是用结节自带模块crpto进行解密,当然,你也可以用节点-RSA的方法进行解密。

最后

我们再来看一看前端请求的密码信息:

这样一串字符,即便被他人获取,如果没有密钥,在一定程度上,他是无法知道你的密码的。

当然,关于网络安全是一个大话题,本篇只是对其中的一小部分进行介绍,欢迎留言讨论,希望对您有帮助。也希望大家多多支持我们。

版权声明:节点中的密码安全性(加密)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。