前言
在开发的时候,有一些敏感信息是不能直接通过明白直接保存到数据库的。最经典的就是密码了。如果直接把密码以明文的形式入库,不仅会泄露用户的隐私,对系统也是极其的不厉,这样做是非常危险的。
一、常规的登录认证(非安全性)
数据库表如下所示:
登录表单:
<template>
<div>
<el-card class="login-form-layout">
<el-form
autocomplete="on"
:model="loginForm"
ref="loginForm"
label-position="left"
>
<div style="text-align: center">
<svg-icon icon-class="login-mall" style="width: 56px;height: 56px;color: #409EFF"></svg-icon>
</div>
<h2 class="login-title color-main">登录页面</h2>
<el-form-item prop="username">
<el-input
name="username"
type="text"
v-model="loginForm.username"
autocomplete="on"
placeholder="请输入用户名"
>
<span slot="prefix">
<svg-icon icon-class="user" class="color-main"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
name="password"
:type="pwdType"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on"
placeholder="请输入密码"
>
<span slot="prefix">
<svg-icon icon-class="password" class="color-main"></svg-icon>
</span>
<span slot="suffix" @click="showPwd">
<svg-icon icon-class="eye" class="color-main"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item style="margin-bottom: 60px">
<el-button
style="width: 100%"
type="primary"
:loading="loading"
@click.native.prevent="handleLogin"
>登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
用户通过表单提交用户名,密码两个字段查询数据库匹配,实现登录认证功能,但存在的安全隐患问题:
1、数据库密码以明文的形式进行存储。
2、数据传输的过程中未对数据进行加密处理。
二、MD5加密
安全加密:首先对数据库表的password字段进行摘要md5处理,sql语句如下
md5加密后的数据
数据库密码加密后,校验的逻辑就发生了些变化,需要对提交的密码进行加密之后再做对比,但是这样是不安全。
1、通过以上步骤,我们只对数据库的password明文字段进行了简单的MD5加密,进入http://www.cmd5.com/
把刚才生成的MD5加密后的密码进行解密。轻松破解,别说黑客了,这个网站都能破解出来,那风险有多大就不用说了。
2、容易根据密文位数推测算法,从而使用工具破解。
3、真实密码相同,加密过的密码也相同。
三、MD5加盐处理
- 什么是盐?
盐(salt)一般是一个随机生成的字符串或者常量。我们将盐与原始密码连接在一起(放在前面或后面都可以),然后将拼接后的字符串加密。salt这个值是由系统随机生成的,并且只有系统知道。即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,散列值也是不同的。
加salt可以一定程度上解决这一问题。所谓加salt方法,就是加点“佐料”。
这样也就变成了将密码+自定义的盐值来取MD5。但是如果黑客拿到了你的固定的盐值,那这样也不安全了。所以比较好的做法是用随机盐值。用户登陆时再根据用户名取到这个随机的盐值来计算MD5。
在表中添加一列salt字段(盐),内容随意输入abc,然后和原来的明文密码123456结合,再进行md5加密。
进行MD5加盐:
加密后:
说明:所谓的salt字段就是一个随机的字段,具体随机算法就不讨论了,每当用户注册账户时,由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。
以上的步骤我们只是对数据库进行了加密,为了防止用户输入密码在传输的过程中被抓包工具获取,我们还要在密码传输的过程中进行加密,这样可以使得获取到的也是密文。
四、BCrypt加盐加密
经过BCryptPasswordEncoder加密后的内容,不需要专门的salt字段存储盐,而是在密文中。
1、BCrypt密码图解:
Bcrypt有四个变量:
saltRounds: 正数,代表hash杂凑次数,数值越高越安全,默认10次。
myPassword: 明文密码字符串。
salt: 盐,一个128bits随机字符串,22字符
myHash: 经过明文密码password和盐salt进行hash
2、校验正确性
在校验时,从密文中取出盐salt,salt跟password进行hash,得到的结果跟保存在DB中的hash进行比对。
五、总结
加密真的很重要,重要的信息千万不能以明文保存。对于用户的密码保护,数据库对敏感的字符内容一定要进行加密之后存储。
通过对密码加盐(混入随机字符拼接在密码明文中)之后加密,可以增加系统复杂度,得到更强更安全的密文摘要值。
版权归原作者 宝爷~ 所有, 如有侵权,请联系我们删除。