• 前端使用bcrypt对密码加密,服务器对密码进行校验


    以前为了防止前端密码安全问题,都是对密码进行md5(password + salt)。
    有些也会用别的加密方式,但还是会存在撞库,彩虹表等破解常规密码。
    因此使用bcrypt加密是一个不错的选择,因为每次加密都会随机salt,每次加密结果都不一样,相对安全性更高些。

    下面是一个示例代码,启动一个http服务器,浏览器输入http://127.0.0.1:8080,当填入密码与服务器一致时提示成功,不一致时报错。

    package main
    
    import (
    	"flag"
    	"fmt"
    	"golang.org/x/crypto/bcrypt"
    	"net/http"
    )
    
    func main() {
    	pass := flag.String("p", "admin", "check password")
    	flag.Parse()
    	password := []byte(*pass)
    
    	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    		w.Write(html)
    	})
    	http.HandleFunc("/users/login", func(w http.ResponseWriter, r *http.Request) {
    		hashedPassword := r.FormValue("pass")
    		fmt.Println(hashedPassword)
    		err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), password)
    		if err != nil {
    			fmt.Fprintln(w, err)
    		} else {
    			fmt.Fprintln(w, "password ok")
    		}
    	})
    	http.ListenAndServe(":8080", nil)
    }
    
    var html = []byte(`<!DOCTYPE html>
    <html>
    <head>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/dcodeIO/bcrypt.js/dist/bcrypt.min.js"></script>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/jquery/jquery@3.2.1/dist/jquery.min.js"></script>
    </head>
    <body>
    <p>密码: <input id="pass" type="password" name="pass"/></p>
    <button type="button" onclick="login()">提交</button>
    <script type="text/javascript">
    function login() {
    	/* https://github.com/dcodeIO/bcrypt.js */
    	var bcrypt = dcodeIO.bcrypt;
    	/* 将密码加密提交 */
    	$.post('/users/login',{pass: bcrypt.hashSync($('#pass').val(), 8)},
            function(result) {
                alert(result);
            }
        );
    }
    </script>
    </body>
    </html>`)
    

    该方案实际还是有一个问题,就是前端加密传输的文本是无法解密的。服务器只能用正确的密码同前端传上去的密文进行相同的加密规则比较密文是否一致。
    此时服务器要么存明文密码,要么对密码做非对称加密,因为服务器是需要明文密码。以前使用md5值hash时,服务器直接存hash后的字符串,因此是没有问题的。
    服务器存明文会存在密码泄露的风险,对密码做非对称或对称加密都会对服务器造成一些性能损耗。而且最终密码是可破解的。
    有想过一个方案就是,前端初始获取rsa公钥,密码使用公钥加密,服务器使用私钥解密,然后把密码进行hash与数据库里面的hash值比较。有些人觉得这是多此一举。
    总之各个方案都有各个方案的优缺点吧。

    作者:janbar
    本文版权归作者和博客园所有,欢迎转载,转载请标明出处。喜欢我的文章请 [关注我] 吧。
    如果您觉得本篇博文对您有所收获,可点击 [推荐] [收藏] ,或到右侧 [打赏] 里请我喝杯咖啡,非常感谢。
  • 相关阅读:
    Git commit 信息标准和丢弃必须要的commit
    Markdown list状态下插入代码
    INIT: vesion 2.88 booting
    I.MX6 support eMMC 5.0
    GitLab non-standard SSH port
    PenMount Touch显示鼠标指针驱动安装
    Android WebView remote debugging
    Android预安装可卸载程序
    jmeter(六)元件的作用域与执行顺序
    jmeter(五)JDBC Request
  • 原文地址:https://www.cnblogs.com/janbar/p/14607659.html
Copyright © 2020-2023  润新知