node中的密码安全(加密)

本文将讲解对于前后端分离的项目,前端注册或登录时如何保证用户密码安全传输到server端,最终存入数据库

为什么需要加密

加密真的有必要吗?

我们先来看一看前端发起的ajax请求中,如果不对密码进行加密,会发生什么。

f12打开chrome开发者工具,找到请求,查看请求参数如下:

如果你的协议是http,那么前端传给后端的密码差不多是裸奔状态,因为http传输的是明文,很可能在传输过程中被窃听,伪装或篡改。

那么,弄个https不就好了吗?

https的确能够极大增加网站的安全性,但是用https得先买证书(也有免费的),对于个人站点或者不想弄证书的情况下,那最起码也得对用户密码进行一下加密吧。

流程图

先看一下大体流程图,首先,我们用工具生成公钥和私钥,将其放入server端,前端发起请求获取公钥,拿到公钥后对密码进行加密,然后将加密后的密码发送到server端,server端将用密钥解密,最后再用sha1加密密码,存入数据库。

生成RSA公钥和密钥

既然选择RSA加密,那么首先得有工具啊,常见的有openssl,但这里不介绍,感兴趣的请自行查阅,对于node而言,我介绍一个不错的库Node-RSA,我们将用它来生成RSA公钥和密钥。

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

用Node-RSA生成的公钥和密钥代码如下:

const NodeRSA = require('node-rsa')
const fs = require('fs')

// Generate new 512bit-length key
var key = new NodeRSA({b: 512})
key.setOptions({encryptionScheme: 'pkcs1'})

var privatePem = key.exportKey('pkcs1-private-pem')
var publicDer = key.exportKey('pkcs8-public-der')
var publicDerStr = publicDer.toString('base64')

// 保存返回到前端的公钥
fs.writeFile('./pem/public.pem', publicDerStr, (err) => {
 if (err) throw err
 console.log('公钥已保存!')
})
// 保存私钥
fs.writeFile('./pem/private.pem', privatePem, (err) => {
 if (err) throw err
 console.log('私钥已保存!')
})

执行完成后,我们将在根目录下得到公钥和私钥文件:

注意:server端的公钥和密钥应该隔一段时间换一次,比如每次服务器重启时。

前端加密

核心代码如下:

 <script src="https://cdn.bootcss.com/jsencrypt/2.3.1/jsencrypt.min.js"></script>
 <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
 <script>
  function reg() {
   axios({
    method: 'post',
    url: 'http://127.0.0.1:3000/getPublicKey'
   })
    .then(res => {
     let result = res.data

     // 从后端获取的公钥 String
     var publicPem = result
     // 用JSEncrypt对密码进行加密
     var encrypt = new JSEncrypt()
     encrypt.setPublicKey(publicPem)
     var password = 'abc123'
     password = encrypt.encrypt(password)

     axios({
      method: 'post',
      url: 'http://127.0.0.1:3000/reg',
      data: {
       password: password
      }
     })
      .then(res => {
       let result = res.data
       console.log(result)
      })
      .catch(error => {
       console.log(error)
      })
    })
  }
 </script>

前端将用到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.use(express.json());

// CORS 注意:要放在处理路由前
function 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.end('ok')
  return
 }

 switch (req.url) {
  case '/getPublicKey':
   let publicPem = fs.readFileSync('./pem/public.pem', 'utf-8')
   res.json(publicPem)
   break
  case '/reg':
   // 解密
   var privateKey = fs.readFileSync('./pem/private.pem', 'utf8')
   var password = req.body.password
   var buffer2 = Buffer.from(password, 'base64')
   var decrypted = crypto.privateDecrypt(
    {
     key: privateKey,
     padding: crypto.constants.RSA_PKCS1_PADDING // 注意这里的常量值要设置为RSA_PKCS1_PADDING
    },
    buffer2
   )
   console.log(decrypted.toString('utf8'))

   // sha1加密
   var sha1 = crypto.createHash('sha1');
   var password = sha1.update(decrypted).digest('hex');
   console.log('输入到数据库中的密码是: ', password)
   // 存入数据库中
   // store to db...
   res.end('reg ok')
   break
 }
})

app.listen(3000, '127.0.0.1')

这里,我是用node自带模块crpto进行解密,当然,你也可以用Node-RSA的方法进行解密。

最后

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

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

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

(0)

相关推荐

  • nodejs中密码加密处理操作详解

    本文实例讲述了nodejs中密码加密处理操作.分享给大家供大家参考,具体如下: 一.关于node加密模块crypto的介绍 其实就是使用MD5加密的,不太安全,在实际开发中根据自己的方案进行加盐处理 二.在路由视图中使用加密方式 1.导入node自带的加密模块(不需要安装) //导入加密模块 const crypto = require("crypto"); 2.做一个用户注册,密码加密的视图 <div class="col-md-6"> <h4&

  • nodejs密码加密中生成随机数的实例代码

    之前关于写了一个 nodejs密码加密中生成随机数,最近需要回顾,就顺便发到随笔上了 方法一: Math.random().toString(36).substr(2)运行后的结果就是11位数的随机数 方法二: 1.定义函数 function randomWord(randomFlag, min, max){ var str = "", range = min, arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',

  • NodeJS实现不可逆加密与密码密文保存的方法

    本文实例讲述了NodeJS实现不可逆加密与密码密文保存的方法.分享给大家供大家参考,具体如下: 在应用中,常常有要将用户的密码加密储存的需要. 以明文保存密码有个缺点:一旦泄漏时容易造成极大的损失,可能会连带其他网站的用户.密码也造成损失(因为大多数用户在多数网站使用相同的账号与密码). 这个泄漏可能来自于两方面:骇客入侵与运维人员监守自盗. 为了防止在密码明文泄漏,我们需要对在数据库中保存的密码字段进行不可逆加密.准确地说,是加密以后再保存到数据库中. 常用的不可逆加密算法有MD5与SHA-1

  • nodejs开发微信小程序实现密码加密

    微信小程序开发--实现密码加密具体步骤: 在utils中的util.js 文件中增加 函数 实现 字符串转换为16进制加密后的字符串: function encodeUTF8(s) { var i, r = [], c, x; for (i = 0; i < s.length; i++) if ((c = s.charCodeAt(i)) < 0x80) r.push(c); else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x

  • node中的密码安全(加密)

    本文将讲解对于前后端分离的项目,前端注册或登录时如何保证用户密码安全传输到server端,最终存入数据库 为什么需要加密 加密真的有必要吗? 我们先来看一看前端发起的ajax请求中,如果不对密码进行加密,会发生什么. f12打开chrome开发者工具,找到请求,查看请求参数如下: 如果你的协议是http,那么前端传给后端的密码差不多是裸奔状态,因为http传输的是明文,很可能在传输过程中被窃听,伪装或篡改. 那么,弄个https不就好了吗? https的确能够极大增加网站的安全性,但是用http

  • node中的session的具体使用

    前言 在上一篇中node中的cookie,对cookie进行了相关介绍,本篇将继续前行,对session进行说明. session是什么 session不就是会话嘛,那什么是会话呢? 会话是一个比连接粒度更大的概念,一次会话可能包含多次连接,每次连接都被认为是会话的一次操作. 当用户在Web页面之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去. 当用户请求来自应用程序的 Web 页面时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Sessi

  • PHP中的密码加密的解决方案总结

    层出不穷的类似事件对用户会造成巨大的影响,因为人们往往习惯在不同网站使用相同的密码,一家"暴库",全部遭殃 一般的解决方案. 1.将明文密码做单向hash $password = md5($_POST["password"]); 2.密码+salt后做单向hash,PHP内置了hash()函数,你只需要将加密方式传给hash()函数就好了.你可以直接指明sha256, sha512, md5, sha1等加密方式 <?php function generate

  • SpringBoot配置文件中数据库密码加密两种方案(推荐)

    SpringBoot项目经常将连接数据库的密码明文放在配置文件里,安全性就比较低一些,尤其在一些企业对安全性要求很高,因此我们就考虑如何对密码进行加密. 介绍两种加密方式:jasypt 可加密配置文件中所有属性值; druid 自带了加解密,可对数据库密码进行加密. jasypt 加解密 jasypt 是一个简单易用的加解密Java库,可以快速集成到 Spring 项目中.可以快速集成到 Spring Boot 项目中,并提供了自动配置,使用非常简单. 步骤如下: 1)引入maven依赖 <de

  • Django中密码的加密、验密、解密操作

    简单介绍一下今天使用到的django内置的加解密包: from django.contrib.auth.hashers import make_password 如上图所示,django.contrib.auth.hashers即为django内置的加解密包. 小提示: pycharm中的Python Console(如下图所示)可以执行django的语句,类似python解释器. 1.加密 语句:make_password(原始密码[,固定字串][,加密方式]) return 加密后的密码 m

  • SpringBoot配置文件中密码属性加密的实现

    目录 背景 集成jasypt-spring-boot到项目中 配置文件配置加密与读取 工作原理简析 使用自定义的加密算法 结语 本文主要介绍了SpringBoot配置文件中的明文密码如何加密保存,读取以及对于自定义的加密算法加密的参数如何保存和读取. 背景 为了安全的需要,一些重要的信息比如数据库密码不能明文保存在配置文件中,需要进行加密之后再保存.SpringBoot可以使用jasypt-spring-boot这个组件来为配置属性提供加密的支持. 集成jasypt-spring-boot到项目

  • 在node中使用jwt签发与验证token的方法

    1.什么是token token的意思是"令牌",是服务端生成的一串字符串,作为客户端进行请求的一个标识. token是在服务端产生的.如果前端使用用户名和密码向服务端发送请求认证,服务端认证成功,那么在服务端会返回token给前端. 前端可以在每次请求的时候带上token证明自己的合法地位.如果token在服务端持久化,那他就是一个永久的身份令牌. 2.什么是jwt jwt,即JSON Web Token的缩写,是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于在

  • php中base64_decode与base64_encode加密解密函数实例

    本文实例讲述了php中base64_decode与base64_encode加密解密函数.分享给大家供大家参考.具体分析如下: 这两个函数在php中是用得对php代码进行加密与解密码的base64_encode是加密,而base64_decode是解密了,下面我们看两个简单实例. base64_encode语法:string base64_decode(string data); 复制代码 代码如下: $str='d3d3LmpiNTEubmV0IOiEmuacrOS5i+Wutg==';   

  • 在JSP中如何实现MD5加密的方法

    在各种应用系统的开发中,经常需要存储用户信息,很多地方都要存储用户密码,而将用户密码直接存储在服务器上显然是不安全的,本文简要介绍在JSP中如何实现MD5加密的方法,希望能抛砖引玉. (一)消息摘要简介 一个消息摘要就是一个数据块的数字指纹.即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组).消息摘要是一种与消息认证码结合使用以确保消息完整性的技术.主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前广泛使用

  • 详谈PHP中的密码安全性Password Hashing

    如果你还在用md5加密,建议看看下方密码加密和验证方式. 先看一个简单的Password Hashing例子: <?php //require 'password.php'; /** * 正确的密码是secret-password * $passwordHash 是hash 后存储的密码 * password_verify()用于将用户输入的密码和数据库存储的密码比对.成功返回true,否则false */ $passwordHash = password_hash('secret-passwo

随机推荐