密码学:密码加密

概述

本文主要讲解通过运用HASH算法,给用户的密码进行加密的各种方案。
对于网络传输数据(隐私数据)和 本地保存数据(隐私数据)都有一个原则,不能明文,一定是加密后的数据。最常见的就是用户的账户密码。

用户在设置密码的时候各类App很可能是同一个密码,如果泄露问题会很严重。

密码加密策略

对于用户的密码,我们可以采用以下策略:

1. RSA

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

2.HASH

这里有个问题是由于HASH值相同,那么可以通过保存HASH值找到明文。如果保存足够多常用密码的HASH值那么通过对照一样能找到明文。
有一个网站cmd5可以直接查询:

image.png

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

3.hash+salt

比如:

static NSString *kSaltKey = @"Hotpot";
NSString *pwd = @"123456";
pwd = [pwd stringByAppendingString:kSaltKey].md5String;
NSLog(@"%@",pwd);

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

4.hmac

NSString *pwd = @"123456";
pwd = [pwd hmacMD5StringWithKey:@"Hotpot"];
NSLog(@"%@",pwd);

这里的keysalt有什么区别呢?本质上没有区别(hmac两次md5),这个key由服务器提供(一个账号一个key)。
这个时候整个流程如下:

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

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

5.hmac+时间戳

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

image.png

hmac+时间戳hmac区别:

  • 加密逻辑不变,不过多了一个时间戳
  • 服务端验证逻辑变了

整个过程如下:

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

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

总结

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

你可能感兴趣的:(密码学:密码加密)