当前位置: 首页 > 后端技术 > Node.js

节点中的密码安全

时间:2023-04-04 01:03:19 Node.js

这篇文章将讲解前后端分离的项目在前端注册或登录时,如何保证用户密码安全传输到服务器,以及为什么数据库中的最终存储需要加密。加密真的有必要吗?我们先来看看如果前端发起的ajax请求中密码没有加密会怎么样。f12打开chrome开发者工具,找到请求,查看请求参数如下:如果你的协议是http,那么前端传给后端的密码几乎是裸奔状态,因为http传输的是明文,并且很可能在传输过程中被窃听。伪装或篡改。那么,拥有https不是很好吗?https确实可以大大增加网站的安全性,但是使用https需要先购买证书(也有免费的)。对于个人网站或者不想拿证书的话,至少要加密用户密码。流程图先来看一下大致的流程图。首先,我们使用工具生成公钥和私钥,并放入服务器。前端发起获取公钥的请求。得到公钥后,对密码进行加密,再对加密后的密钥进行加密。密码发送到服务器,服务器用密钥解密,最后用sha1加密密码存入数据库。生成RSA公钥和密钥既然选择了RSA加密,首先要有一个工具。常见的是openssl,这里就不介绍了。如果您有兴趣,请自行查看。对于节点,我介绍了一个很好的库Node-RSA,我们将使用它来生成RSA公钥和私钥。RSA是一种非对称加密算法,即由密钥和公钥组成的密钥对,由密钥加密,由公钥解密,或者由公钥加密,由密钥解密。其中,公钥可以公开,但密钥必须保密。Node-RSA生成的公钥和密钥代码如下:constNodeRSA=require('node-rsa')constfs=require('fs')//Generatenew512bit-lengthkeyvarkey=newNodeRSA({b:512})key.setOptions({encryptionScheme:'pkcs1'})varprivatePem=key.exportKey('pkcs1-private-pem')varpublicDer=key.exportKey('pkcs8-public-der')varpublicDerStr=publicDer.toString('base64')//保存返回给前端的公钥fs.writeFile('./pem/public.pem',publicDerStr,(err)=>{if(err)throwerrconsole.log('publickeySaved!')})//保存私钥fs.writeFile('./pem/private.pem',privatePem,(err)=>{if(err)throwerrconsole.log('私钥已保存!')})执行完成后,我们会得到根目录下的公钥和私钥文件:注意:服务器端的公钥和私钥要每隔一段时间更改一次,例如每次服务器重新启动时。前端加密核心代码如下:前端会使用jsencrypt加密,详细使用方法参考github后端解密后端核心代码:constexpress=require('express');constcrypto=require('crypto');constfs=require('fs');varprivatePem=fs.readFileSync('./pem/private.pem');varapp=express();app.use(express.json());//CORS注意:在处理路由函数之前crossDomain(req,res,next){res.header('Access-Control-Allow-Origin','*');res.header('Access-Control-Allow-Headers','Content-Type');next();}app.use(crossDomain)app.use(function(req,res,next){//如果不加,会报错if(req.method==='OPTIONS'){res.结束('确定')返回}开关(req.url){案例'/getPublicKey':让publicPem=fs.readFileSync('./pem/public.pem','utf-8')res.json(publicPem)breakcase'/reg'://解密varprivateKey=fs.readFileSync('./pem/private.pem','utf8')varpassword=req.body.passwordvarbuffer2=Buffer.from(password,'base64')vardecrypted=crypto.privateDecrypt({key:privateKey,padding:crypto.constants.RSA_PKCS1_PADDING//注意这里的常量值要设置为RSA_PKCS1_PADDING},buffer2)console.log(decrypted.toString('utf8'))//sha1加密varsha1=crypto.createHash('sha1');变种密码=sha1。更新(解密).digest('hex');console.log('输入数据库的密码是:',password)//存入数据库//存到db...res.end('regok')break}})app.listen(3000,'127.0.0.1')这里我使用node自带的模块crpto进行解密。当然你也可以使用Node-RSA的方式来解密。最后看一下前端请求的密码信息:这样一串字符,即使别人拿到了,如果没有密钥,他在一定程度上是无法知道你的密码的。当然,网络安全是一个很大的话题,本文只介绍其中的一小部分。欢迎留言讨论,希望对您有所帮助。