07-密码学(3)

前言

本篇文章,将继续讲解密码学算法的另一个算法 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位32个字符(16进制标识)
  • 无法逆运算。(那么则无法做加密
  • 信息摘要,信息指纹,用来做数据识别
为什么无法逆运算?

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

2.3 用途

  • 对用户密码的加密,这个上面说过
  • 搜索引擎
    比如: iOS SwiftSwift iOS 搜索出来的结果可能相同。这里词有hash值,将多个词的hash值拿到加到一起。
  • 版权
    任意文件都会生成一个hash值。上传平台后平台会保存原始文件hash值。别人下载的文件不是原文件(平台生成)。这个时候平台就可以通过原文件hash来区分确定版权问题了。
  • 网盘
    数据识别-hash
  • 数字签名

数字签名

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

  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]);

运行

示例代码

XFCryptor的NSString+Hash分类

总结

  • 加密策略

    • RSA 泄露可能性低,但是开发者知道密码,数据库泄露可能
    • HASH 可能被暴力破解(查表)
    • HASH+salt 盐可能泄露(这里为固定盐
    • HMAC 比较好的方案,问题是加密后的数据有可能被截获
    • HASH+时间戳 保证每次加密结果受时间影响,相对比较安全
  • HASH

    • 特点:
      • 算法公开
      • 不可逆运算(多对一)
      • 相同数据加密结果相同
      • 不同长度数据加密结果定长
      • 一般用于数据的识别(密码,版权,网盘)
    • 用途:
      • 密码加密,详见加密策略
      • 搜索引擎
      • 版权
      • 网盘
      • 数字签名
        • 算法:HASH+RSA
        • 目的:验证数据的完整性不被篡改
        • 逻辑:
          1. 原始数据进行Hash
          2. 使用RSA机密HASH值(这部分数据就是原始数据的数字签名)
          3. 将原始数据+数字签名一起发送传递(客户端使用公钥解密验证)

你可能感兴趣的:(07-密码学(3))