“记住密码” 和 “用户名和密码”加密传输 crypto-js(对称加密) JSEncrypt(非对称加密)

参考

  1. RSA非对称加密传输—前端加密&解密(VUE项目)
  2. crypto-js 加密库学习笔记
  3. 公钥和私钥,有在线生成器

问题描述

经常在管理程序中经常能看到 “记住密码” 和 “用户名和密码”登录的界面,如图:

在这里插入图片描述

问题:

  1. 如何保证下次进入项目能继续获取用户的账号和密码
  2. 登录账号和密码如果明文传输,如果懂前端开发,不就可以很容易获取账号和密码了吗,很不安全

如何保证下次进入项目能继续获取用户的账号和密码?

解决办法:如果用户选择“记住账号”,则将用户的输入内容保存到cookie中

如果直接保存账号和密码,那么用户可以很容易直接通过开发控制台查看账号和密码,很不安全,这个和直接用账户和密码直接登录明文传输的风险是一样的,不安全。

import Cookies from "js-cookie";
import {encrypt} from "@/util/jsencrypt";

export default {
  created() {
    this.getCookie();
  },
  methods: {
    getCookie() {
      const username = Cookies.get("username");
      const password = Cookies.get("password");
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        // 从cookie中获取密码,然后解密
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
        code: "",
        redomStr: "",
      };
    },
    // 点击登录
    handleLogin() {
      // 如果是要记住密码
      if (this.loginForm.rememberMe) {
        Cookies.set("username", this.loginForm.username, {expires: 30});
        // 对用户的输入加密,保存到cookie中
        Cookies.set("password", encrypt(this.loginForm.password), {expires: 30});
        Cookies.set('rememberMe', this.loginForm.rememberMe, {expires: 30});
      } else { // 不记住密码
        Cookies.remove("username");
        Cookies.remove("password");
        Cookies.remove('rememberMe');
      }
      // 提交登录信息
      this.$store.dispatch("LoginByUsername", this.loginForm).then(() => {
      }).catch(() => {
      })
    }
  },
}

}

如何保证登录账号的安全?

解决办法:将用户登录的账号和密码加密,然后将加密的字符串提交给后端,后端然后解密字符串,获取用户的账号和密码,然后匹配登录

利用这个思路,同理,保存密码,也是可以将加密的字符串保存到cookie中,然后通过解密,获取到原始的账号和密码

加密和解密的过程,推荐使用 非对称加密

加密方式介绍

对称加密

简单理解就是加密和解密使用相同的秘钥,由于前端代码是完全暴露在外面的,某些人可以通过源码查找到秘钥,从而解密,因此不安全

  1. 定义crypto-js加密 / 解密 方法
import CryptoJS from 'crypto-js';
 
export default {
    //随机生成指定数量的16进制key
    generatekey(num) {
        let library = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let key = "";
        for (var i = 0; i < num; i++) {
            let randomPoz = Math.floor(Math.random() * library.length);
            key += library.substring(randomPoz, randomPoz + 1);
        }
        return key;
    },
    
    //加密
    encrypt(word, keyStr) {
        keyStr = keyStr ? keyStr : 'abcdsxyzhkj12345'; //判断是否存在ksy,不存在就用定义好的key
        var key = CryptoJS.enc.Utf8.parse(keyStr);
        var srcs = CryptoJS.enc.Utf8.parse(word);
        var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        return encrypted.toString();
    },
    //解密
    decrypt(word, keyStr) {
        keyStr = keyStr ? keyStr : 'abcdsxyzhkj12345';
        var key = CryptoJS.enc.Utf8.parse(keyStr);
        var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        return CryptoJS.enc.Utf8.stringify(decrypt).toString();
    }
 
}
  1. 测试
// var keys = AES.generatekey(16);
 
//如果是对象/数组的话,需要先JSON.stringify转换成字符串
// 不传key值,就默认使用上述定义好的key值
 
var encrypts = AES.encrypt(JSON.stringify(cars));
var dess = JSON.parse(AES.decrypt(encrypts));
 
// var encrypts = AES.encrypt('1234asdasd');
// var dess = AES.decrypt(encrypts);
 
console.log(encrypts)
console.log(encrypts.length)
console.log(dess)

非对称加密

公钥用来加密,任何人都知道,私钥在服务器,只有通过私钥可以解密密文,及时黑客拿到了公钥和密文,也无法解密

  1. JSEncrypt 加密 / 解密
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'

// 密钥对生成 http://web.chacuo.net/netrsakeypair

const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcMTbFitfOemx/8tcasryDRQk3\n' +
  'Y7Zp8szBM03xbH3s+umdI5blcUdPLs4NEH9qojFoiCb7nPg92MXEfaXy9gNZ7Qft\n' +
  'OsU5XQRhySp6e/NdbRHut1ksvJXnlUc+OLFW6RIZgHwqmsZrlWRo71MXOBoPcpss\n' +
  'VEFfqFmzDY0Nw7zUKQIDAQAB'

const privateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANwxNsWK1856bH/y\n' +
  '1xqyvINFCTdjtmnyzMEzTfFsfez66Z0jluVxR08uzg0Qf2qiMWiIJvuc+D3YxcR9\n' +
  'pfL2A1ntB+06xTldBGHJKnp7811tEe63WSy8leeVRz44sVbpEhmAfCqaxmuVZGjv\n' +
  'Uxc4Gg9ymyxUQV+oWbMNjQ3DvNQpAgMBAAECgYEAhU+Od58N9UaNdhGSRem81ETx\n' +
  'xYUrJY4IhVgIcoha3SU0Vxz6+MLSh5Aw1BwO6IJ2I3F7GI76hIc/hS0FUcm8UI9r\n' +
  '9QrDp9LC5lQjD8kjnLCRpKwF9fSv76asWHhKsvTDVZvsxJhuVKd6SSmFYSC5EgNx\n' +
  'uVn5PeTLCYzpNtJ6IlkCQQD9FsGOilFltYiXZWNvfdsCCBmzOQUzmoU3G/WOQHyy\n' +
  '3ue/cOYOmygDNjxm2aqBx6TAD7fs0ErnD6xnwgM6jgWnAkEA3rmXMjTgT7Ux5uE1\n' +
  'RKwUvzVPZgyNt3mvabfTU6ROFD99Rbgf7nb6Fa1+DFKXu6mxoHE6mL5c/Z8mjyru\n' +
  'fB4xrwJAFFAbQOGBHvSu/de5X11ukn8r8OKGtFmWj5HC56PtXj3dw9O/4zQ4xek4\n' +
  'd9jIgpoPcwrP7EXbfSgY4ksED1MOyQJATMjrCVIVayVquNA3jx9MX8c/Qk1dpj17\n' +
  'bhUD9DgW+wAQbjLWP14hRcv0QsdOrFIKfOfMbdBjOsTdhEomwf+e3QJBAI3y7+Z/\n' +
  '+KWOirIjXsWmGZAJSBuF4v3s5mK9lMcBBkTUggz+MwAP9gbvWkSc0jpuMGGpigKE\n' +
  'pUm/fr5oXLkGSAA='


// 加密
export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(txt) // 对数据进行加密
}

// 解密
export function decrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decrypt(txt) // 对数据进行解密
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值