密码学

密码学概论

原则:

  1. 在网络上不允许明文传输用户隐私信息;
  2. 在本地不允许明文保存用户隐私信息;

base64 编码

base64 编码:将二进制数据编码成只有65个字符文本文件(字符)!

base64 编码包括的字符:0 ~9, a~z, A~Z, +/=

编码后文件数据会比原有文件大1/3左右。

原理

base64 编码:8位的二进制ASCII编码 —> 6位的base64编码

base64编码表:

0~63,64个字符,还有 = 表示空格,总共65个字符。

密码学_第1张图片

示例:

密码学_第2张图片

Man 转换为 base64 编码:TWFu

M 的 ASCII编码 十进制为 77 ,二进制为 01001101:

前6位二进制 010011 (十进制为19)在上面的base64编码表中为 T 。

因此 M ➡ T 。

空格情况

因为是把8个字节转换为6个字节进行编码,势必会产生位数不对应的问题。因此会使用 0 来补齐,用=表示全0的情况。(注意到base64 总会编码补齐为4个字符一组)

密码学_第3张图片

因此,单独的 M 用base64编码 ➡ TQ==

Objective-C 代码

// base64编码
- (NSString *)base64Encode:(NSString *)string {
    // 1.将字符串转换为二进制
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    // 2.二进制数据进行编码
    return [data base64EncodedStringWithOptions:0];
}

// base64解码
- (NSString *)base64Decode:(NSString *)string {
    // 1.字符串转换为二进制
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
    // 2.解码
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

哈希、对称加密、非对称加密

上世纪70年代开始 RSA — 非对称加密算法

RSA — 非对称加密算法

  • 公钥加密,私钥解密;
  • 私钥加密,公钥解密;

哈希(散列)函数

  • MD5
  • SHA1\SHA256\SHA512
  • HMAC

对称加密算法

  • DES
  • 3DES
  • RC2、RC4
  • AES(高级密码标准,美国国家安全局使用、Apple 钥匙串访问使用、Lastpass 使用了256位的AES密钥),以目前现阶段计算机的运行效率,要暴力破解AES加密算法,需要上千万年。

散列函数

算法都是公开的。

  • 对相同的数据加密,得到的结果是一样的。
  • 对不同的数据加密,得到的结果是定长的。(比如MD5对不同的数据加密,得到32个字符)
  • 加密之后的数据是没法解密的。(不可逆运算

MD5 哈希算法

GitHub源码:jerilimov/NSHash——NSData、NSString 的分类,添加了MD5、SHA1、SHA256、SHA512 加密算法

NSString *pwd = @"123456";
pwd = [pwd MD5];
NSLog(@"MD5 = %@",pwd);
// MD5 = e10adc3949ba59abbe56e057f20f883e

像 MD5 这样的加密算法是无法反向解密的,但是对相同的数据加密,得到的结果是一样的。

于是 CMD5 利用散列函数的这种特性,将加密前的数据和加密后的数据进行映射保存,可以实现反向查询。

将刚才 123456 加密后的 MD5 输入,可以反向查询出原始数据:

密码学_第4张图片

MD5加盐:对数据先加盐,再进行MD5加密,可以增加结果的复杂度

/* 盐,足够长,足够复杂,足够咸*/
static NSString *slat = @"5O9Jc!9%N^6Kd*dcS9Or$&fSVWmC^xku2@Lg0xd8CL0Sl$omN6zQS7c7YrHhtwn@";

NSString *pwd = @"123456";
pwd = [[pwd stringByAppendingString:slat] MD5];
NSLog(@"MD5 = %@",pwd);
// MD5 = 04f60881265e2b240b217f8deaaa8e12

再将此MD5密码放到该网站上进行查询:

密码学_第5张图片

没有查到,结果显示,被反向查询出来的难度就会加大。

缺点:盐是固定的,如果盐被泄露,数据就会不安全。

注:哈希算法&加密算法的区分

  • MD5、HMAC、SHA 等所有的哈希算法严格上来说并不能称之为加密算法,它只能说是密码学中的哈希算法
  • 加密算法加密之后是可以解密的,而哈希算法无法反向解出原始数据。
  • 哈希算法通常用于校验数据的完整性,例如:校验下载后的安装包文件是否被篡改、删减或植入恶意代码。

HMAC 哈希算法

//-----------------------------------------------------
#import 

@interface NSString (Hash)
- (NSString *)hmacMD5StringWithKey:(NSString *)key;
- (NSString *)hmacSHA1StringWithKey:(NSString *)key;
- (NSString *)hmacSHA256StringWithKey:(NSString *)key;
- (NSString *)hmacSHA512StringWithKey:(NSString *)key;
@end
  
#import "NSString+Hash.h"
#import 
@implementation NSString (Hash)

- (NSString *)hmacMD5StringWithKey:(NSString *)key
{
    return [self hmacStringUsingAlg:kCCHmacAlgMD5 withKey:key];
}
- (NSString *)hmacSHA1StringWithKey:(NSString *)key
{
    return [self hmacStringUsingAlg:kCCHmacAlgSHA1 withKey:key];
}
- (NSString *)hmacSHA256StringWithKey:(NSString *)key
{
    return [self hmacStringUsingAlg:kCCHmacAlgSHA256 withKey:key];
}
- (NSString *)hmacSHA512StringWithKey:(NSString *)key
{
    return [self hmacStringUsingAlg:kCCHmacAlgSHA512 withKey:key];
}
#pragma mark - Helpers
- (NSString *)hmacStringUsingAlg:(CCHmacAlgorithm)alg withKey:(NSString *)key
{
    size_t size;
    switch (alg) {
        case kCCHmacAlgMD5:
            size = CC_MD5_DIGEST_LENGTH;
            break;
        case kCCHmacAlgSHA1:
            size = CC_SHA1_DIGEST_LENGTH;
            break;
        case kCCHmacAlgSHA224:
            size = CC_SHA224_DIGEST_LENGTH;
            break;
        case kCCHmacAlgSHA256:
            size = CC_SHA256_DIGEST_LENGTH;
            break;
        case kCCHmacAlgSHA384:
            size = CC_SHA384_DIGEST_LENGTH;
            break;
        case kCCHmacAlgSHA512:
            size = CC_SHA512_DIGEST_LENGTH;
            break;
        default:
            return nil;
    }
    
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    NSData *messageData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData *mutableData = [NSMutableData dataWithLength:size];
    CCHmac(alg, keyData.bytes, keyData.length, messageData.bytes, messageData.length, mutableData.mutableBytes);
    return [self stringFromBytes:(unsigned char *)mutableData.bytes length:(int)mutableData.length];
}
- (NSString *)stringFromBytes:(unsigned char *)bytes length:(int)length
{
    NSMutableString *mutableString = @"".mutableCopy;
    for (int i = 0; i < length; i++)
        [mutableString appendFormat:@"%02x", bytes[i]];
    return [NSString stringWithString:mutableString];
}
@end

测试

// HMAC 用一个密钥加密,并且做了两次散列。
// 在实际的开发中,密钥来自于服务器。——对应一个帐号,一个KEY
NSString *pwd = @"123456";
pwd = [pwd hmacMD5StringWithKey:@"Key"];
NSLog(@"MD5 = %@",pwd);
// MD5 = a7cac7471d2c9eb7a944e07d44d305ca

将此MD5密码放到该网站上查询也是查不到的。

项目实际使用流程:

  1. 服务器根据用户帐号生成KEY,发送给客户端;
  2. 客户端获得KEY并保存到本地,使用KEY对数据进行HMAC加密,将加密后的数据发送给服务器;
  3. 服务器对加密后对数据进行验证。

客户端登录时,没有KEY就先根据帐号从服务器获取KEY保存到本地,再将获得的KEY对密码进行加密。

防止KEY泄露,对KEY进行非对称加密、定期更换KEY。

QQ设备锁:

  • 本地有KEY——为授权手机。
  • 本地没有KEY,未授权设备,需要允许服务器发送KEY。允许一次登录,本地不保存KEY,允许多次登录,保存KEY到本地。
  • 短信验证码登录获取KEY。
  • 申诉获取KEY。

HMAC加密+时间戳(不加秒)

之前:

验证方式:HMAC密码直接匹配是否正确。

现在:

客户端:(HMAC密码+“201711010358”).MD5校验

服务器:

  1. (HMAC密码+“201711010359”).MD5校验
  2. (HMAC密码+“201711010358”).MD5校验

密码验证有效期最长2分钟,超过2分钟,验证失败。

有经验的服务器人员,会在返回数据时,返回时间戳。

登录等待时间,不要超过6秒!!!提示用户:你的网络不稳定,请稍后再试!

终端测试命令:

md5 -s "string" #这是 Apple 用的 openssl 标准进行的MD5加密

MD5使用场景,百度搜索引擎(拆词搜索思路)运用 以及百度云盘文件识别运用

搜索引擎的拆词搜索 && 词库

无论搜索 Apple Blue Sky,还是搜索Sky Blue Apple,得到的返回结果是一样的。

原理

先计算各个单词的MD5

  • MD5 ("Apple") = 9f6290f4436e5a2351f12e03b6433c3c
  • MD5 ("Blue") = 9594eec95be70e7b1710f730fdda33d9
  • MD5 ("Sky") = 03462a41aec357b74c89eb8d272532f7

然后再对MD5值进行按位相加,得到的结果是一样的。

再去搜索匹配结果的数据。

散列碰撞:两个不同的数据,哈希之后,得到相同的哈希值!

从理论的角度出发,有无限个碰撞可能!

MD5 32为字符,它能表达的数据个数是有限的,而被加密的数据是无限个。

其他使用场景

通过数据的散列值,判断数据是否相等,保存云盘数据(相同的数据在云上保存一份)。

正版软件使用哈希进行文件识别。

对下载后的软件安装版进行 MD5 校验,判断安装包是否被污染。

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