07-密码学(3)

2021-04-19  本文已影响0人  深圳_你要的昵称

前言

本篇文章,将继续讲解密码学算法的另一个算法 👉 HASH算法。

一、加密策略

在讲解HASH之前,我们来分析一下加密的策略
我们都知道,对于网络传输数据(隐私数据)本地保存数据(隐私数据)都有一个原则 👉 不能明文,一定是加密后的数据。最常见的就是用户的账户密码。对于用户的密码,我们可以采用以下策略👇

  1. RSA

rsa加密网络上数据泄露的可能性低,相对来说比较安全,但是服务端的数据库中保存的是用户的真实密码(明文密码),那如果数据库泄露,所有用户密码将泄露
所以应该有一个原则 👉 服务端不能保存用户的明文密码,最好是开发者都不知道密码。这时用hash再合适不过了。

  1. HASH

HASH也有个问题 👉 是由于HASH计算后值相同,那么可以通过保存HASH值找到明文。如果保存足够多常用密码的HASH值,那么就能通过对照(映射)一样能找到明文

例如,有一个网站cmd5可以直接查询👇

这就是暴力破解了,直接查表就能得到明文了。并且这个网站支持的方式和数据很多,所以直接hash显示仍然是不安全的

  1. HASH+salt
static NSString *kSaltKey = @"LGPerson";
NSString *pwd = @"123456";
pwd = [pwd stringByAppendingString:kSaltKey].md5String;
NSLog(@"%@",pwd);

通过加盐,在注册时服务端直接将加盐后的密码哈希值保存在数据库中。这个方式对开发者依赖太大了,开发者知道salt泄露salt后依然可以还原

  1. hmac
NSString *pwd = @"123456";
pwd = [pwd hmacMD5StringWithKey:@"LGPerson"];
NSLog(@"%@",pwd);

这里的keysalt有什么区别呢?本质上没有区别(hmac两次md5),这个key服务器提供 👉 一个账号一个key
此时流程👇

  1. 注册的时候客户端发请求给服务端,服务端判断账号存不存在不存在的时候服务端生成一个key和账号绑定在一起。
  2. 服务端将key给到客户端,客户端将密码和key通过hmac计算得到hash值返回到服务端。服务端保存这个hash值
  3. 客户端登录的时候拿这个key(本地,一般存储在keychain)密码计算得到hash值登录。

整个过程如下图👇

此时,又有问题来了 👉 如果用户换了手机(没有key)怎么处理呢?
在换手机后先从服务端请求key(RSA加密),这里一般会涉及到授权(旧手机短信,人脸等),没有key则不是认证手机不让登录。请求key需要授权(确定用户是账号的主人)才给key

  1. hmac+时间戳

虽然hmac一般情况下获取不到明文密码了,但是仍然可以获取hamc(密码+key)的值。如果直接用这个hash值服务端交互呢?是不是也会有风险。此时怎么处理呢?这个时候就可以用hash + 时间戳来解决了👇

hmac+时间戳hmac区别

此时流程👇

  1. 客户端将hash值和时间戳 md5后发送给服务端。
  2. 服务端本地时间和数据库中存储的hash值做hash运算,与客户端发送的值做比对
  3. 如果验证失败则拿上一分钟的时间再次验证。这里给了1分钟的容错。hash值有效值时间1分59秒时间可以自定义)。

这个时候hash值就和时间绑定了,就相对安全了,每次加密结果受时间影响

二、HASH

2.1 概述

Hash一般翻译做“散列”,也直接音译为“哈希”,就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。

简单的说就是 👉 一种将任意长度的消息压缩到某一固定长度的消息摘要(指纹)的函数。

常见的HASH算法有👇

  1. MD5
  2. SHA1、256、512

2.2 特点

为什么无法逆运算?

比如对数据进行MD5运算得到的结果是128位,也就是能表达的数据是1632种(有限),那么由于数据(无限)。这里必然有多个数据拥有同样的hash值(散列碰撞)

2.3 用途

数字签名

接下来重点看看数字签名。因为国外喜欢用支票,支票上面的签名能够证明身份。数字签名顾名思义,就是用于鉴别数字信息的方法,确认二进制是不是原始机构签发的。

  1. 二进制数据计算hash值
  2. 签发方对hash值进行rsa加密
  3. 接收方解密获取hash值,并且对二进制文件计算hash值hash值相同则证明是原始文件。

其中,对hash值进行rsa加密后的数据,就叫做这个二进制文件的数字签名

2.4 终端演示

2.4.1 HASH

md5

// 字符串
md5 -s "LGPerson"
//文件
md5 message.txt

上图返回32个字符MD5散列字符串

sha1

//字符串
echo -n "LGPerson" | openssl sha1
//文件
openssl sha1 message.txt

上图返回40个字符SHA1散列字符串

sha256

//字符串
echo -n "LGPerson" | openssl sha256
//文件
openssl sha256 message.txt

SHA256散列字符串64个字符

sha512

//字符串
echo -n "LGPerson" | openssl sha512
//文件
openssl sha512 message.txt

SHA512散列字符串128个字符

2.4.2 HMAC

hmac md5

echo -n "LGPerson" | openssl dgst -md5 -hmac "key"

返回32个字符HMAC MD5散列字符串

hmac sha1

echo -n "LGPerson" | openssl sha1 -hmac "key"

返回40个字符HMAC SHA1散列字符串

hmac sha256

echo -n "LGPerson" | openssl sha256 -hmac "key"

返回64个字符HMAC SHA256散列字符串

hmac sha512

echo -n "LGPerson" | openssl sha512 -hmac "key"

返回128个字符HMAC SHA256散列字符串

读者可自行验证,这里就不再演示了。

2.5 代码演示

iOS中HASH加密解密框架是CommonCrypto

//string
NSString *message = @"LGPerson";
NSString *key = @"key";
NSLog(@"string md5: %@",[message md5String]);
NSLog(@"string sha1: %@",[message sha1String]);
NSLog(@"string sha256: %@",[message sha256String]);
NSLog(@"string sha512: %@",[message sha512String]);
NSLog(@"string hmac md5: %@",[message hmacMD5StringWithKey:key]);
NSLog(@"string hmac sha1: %@",[message hmacSHA1StringWithKey:key]);
NSLog(@"string hmac sha256: %@",[message hmacSHA256StringWithKey:key]);
NSLog(@"string hmac sha512: %@",[message hmacSHA512StringWithKey:key]);

//文件
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"message" ofType:@"txt"];
NSLog(@"file md5: %@",[filePath fileMD5Hash]);
NSLog(@"file sha1: %@",[filePath fileSHA1Hash]);
NSLog(@"file sha256: %@",[filePath fileSHA256Hash]);
NSLog(@"file sha512: %@",[filePath fileSHA512Hash]);

运行👇

示例代码

XFCryptorNSString+Hash分类

总结

上一篇 下一篇

猜你喜欢

热点阅读