hash和对称加密

2019-10-10  本文已影响0人  我是好宝宝_6966

一、hash

1. 什么是hash?

Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数

2. hash的特点

既然hash的运算结果是定长的,那么必然会出现多个数据的hash相同的情况,这被叫做散列碰撞

3. hash的用途
MD5 (001.png) = 794f38b127db2e24e23a59d1fcb7a700

修改名字+后缀名为“md5 002.mp3”,终端命令md5 002.mp3"输出的hash值为

MD5 (002.mp3) = 794f38b127db2e24e23a59d1fcb7a700

修改回“001.png”,Ctrl+C Ctrl+V复制一份图片,命名为“002.png”,终端命令md5 002.png"

MD5 (002.png) = 794f38b127db2e24e23a59d1fcb7a700

将图片打包成“001.zip”,终端命令md5 001.png.zip

MD5 (001.png.zip) = eca9687c64a1a62154582186214a97be

上述操作得出几个结论:
① 修改文件名或后缀名不会改变其二进制(hash值),后缀名其实是给操作系统看的——让操作系统判断用什么软件打开它
② 复制粘贴的本质是对二进制的复制粘贴
③ 只有压缩操作才会改变二进制

由于hash运算的不可逆,让它在很多领域都大放异彩


二、 hash在加密用户密码中的方案

1. 明文请求

如果直接用明文传输密码,黑客能直接抓取到网络请求,用户密码会“一丝不挂”的出现在黑客面前;又如果使用RSA加密传输,客户端加密服务器解密,岂不是美滋滋?但是用户密码还是会明文保存在服务器端,这样是很不安全的!!!
互联网有两个原则:① 网络传输不允许明文传递用户隐私信息;② 本地不允许明文保存用户隐私信息

2. 直接MD5加密/多次MD5加密

那么直接使用MD5加密用户密码呢?或许很多小型外包就是这么处理的,但这种方案也是很不全的,因为hash算法是不可逆的。只要穷举千千万万种hash算法的结果,然后再进行反向查询,用户的密码也会轻而易举会拿到,比如https://www.cmd5.com/这个网站

那我们再尝试尝试多次MD5呢?其实也是一样的,CMD5这个网站可以选择类型进行反向查询,多次嵌套并不管用
3. 加固定盐

加盐是什么意思呢?就是在用户的明文密码后面加一点“作料”——一串奇奇怪怪的字符串,然后再做hash运算,比如“123456da.gjio1ra”再做MD5运算发送给服务器。
这种方案的用户密码不能简单快速的破译出明文密码,但是也能通过暴力破解。与之同时带来一系列的危害:破解出明文密码,也就知道了盐,因为盐是写死的,那么所有用户的密码也都可以轻而易举的破解出来,所以在这种方案中对“盐”的保护尤为重要。其次,各个客户端、服务器都知道“盐”的具体内容,那公司能保证所有开发工程师离职了不透露出去吗?我们做开发的应该做到尽善尽美,不能让这些人为因素影响我们的app安全!
既然写死“盐”不行,那么我们可以用动态盐来解决问题

4. HMAC

HMAC是使用一个密钥加密,并且做两次散列运算,得到一个hash值。它是一种方案,不是加密算法。在实际开发中HMAC的密钥来自于服务器,是随机的,每个账号各不相同
接下来通过多种登录情况理一下登录逻辑:
① 注册


a. 用户在客户端填写好账号、密码等信息后点击注册,开始注册请求,并将账号Feng发送给服务器
b. 服务器对账号Feng进行校验,如果可用的话,随机生成一个密钥key发送给客户端
c. 客户端对进行HMAC,再将账号+密码发送给服务器,服务器将账号Feng+密钥key+密码hmac一一对应保存。然后返回注册成功的请求结果,客户端就能将密钥key存储起来了

这样子一个账号对应一个密钥,大大提高了登录安全性。但是想一下万一用户换了台设备登录,那不是拿不到key了?所以我们还得丰富一下我们的登录逻辑

② 换设备登录


a. 用户在客户端填写好账号、密码等信息后点击登录,客户端现在本地查找账号对应的密钥,如果本地有对应的key直接走c,如果没有的话将账号Feng发送给服务器并请求密钥key
b. 服务器对账号Feng进行查找,将账号对应的密钥key返回给客户端
c. 客户端对明文密码hmac得到密码hmac,将账号Feng+密钥key+密码hmac发送给服务器。如果服务器账号密码匹配成功,客户端将密钥key保存;反之不能保存

③ 设备锁业务


a. 设备B初次登录,并向服务器索要key
b. 服务器询问原设备A是否开始设备锁,如果没开就自定发送key给B;如果开了就向设备A访问权限,A同意了才能发送
b. 服务器对账号Feng进行查找,将账号对应的密钥key返回给客户端
c. 同②-c
  1. 防止被抓去网络请求数据——加时间戳
    HMAC的加密方案已经相当安全了,但是客户端发送给服务器的密码照样能被截取到,第三方只要账号、密码一匹配就能简简单单登录,所以我们要对网络请求数据进行一些处理,我们采用的方法是加时间戳:
    a. 发起登录请求
    b. 服务器返回时间戳给客户端
    c. 照着(HMAC哈希值+时间戳).MD5进行运算,这里的时间戳不是本地的系统时间,而是发起登录请求时服务器返回给客户端的时间戳(只取到分钟)然后将HMAC密码拼接上时间戳,再次进行MD5发送给服务器
    d. 服务器也用同样的算法进行运算,先匹配同一分钟的哈希值,匹配不成功再匹配上一分钟的哈希值

这样做能够让用户的密码随着时间变化而变化,黑客只能在最多两分钟内使用截获到的密码(最少1分01秒,最多1分59秒)

总结:建议用户密码采用先HMAC再时间戳的方案
也有账号动态盐,密码时间戳的方案

三、数字签名

1. 含义

数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。

2. 作用

图文并茂才能更好地阐述观点——xx去银行取十块钱的过程


正常情况下

a. 用户要取10元
b. 银行给了你10元
c. 用户拿到10元


黑客骚扰下
a. 用户要取10元
b. 黑客修改:“用户要取20元”

c. 银行转出20元
d. 黑客拿到10元,用户拿到10元


数字签名后
a. 用户要取10元
b. 黑客想修改成:“用户要取20元”,但修改不了
c. 银行转出20元
d. 用户拿到10元
3. 原理

a. 原始数据HASH加密
b. 使用RSA对HASH值进行加密(数字签名)
c. 将原始数据+数字签名,一起发给服务器验证
黑客没有私钥,不能对其进行解密;
传输过程中,没有密钥传递;
hash值判断原始值有无修改

注:加密数字信息叫数字签名,加密代码叫代码签名,加密引用叫应用签名


四、对称加密

1. 含义:明文通过密钥加密得到密文。密文通过密钥解密得到明文

非对称加密被叫做现代加密算法,对称加密算法则叫做传统加密算法

2. 对称加密算法有三种:
3. 常见的应用模式有两种:
  1. 生成一个message.text
123456123456123456
123456123456123456
123456123456123456
123456123456123456
  1. 终端命令openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out msg1.bin
    用DES加密,选择ECB应用模式,密钥为616263,不加盐
  2. 修改message.text,最后一组123456->223456
123456123456123456
123456123456123456
123456123456123456
123456123456223456
  1. 终端命令xxd msg1.binxxd msg2.bin
    ECB加密结果对比
  2. 同样的操作,选择CBC
    openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out msg3.bin
    openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out msg4.bin
    用DES加密,选择CBC应用模式,初始化向量为0102030405060708,密钥为616263,不加盐
  3. 终端命令xxd msg3.binxxd msg4.bin
    CBC加密结果对比
上一篇下一篇

猜你喜欢

热点阅读