Hash和对称加密

Hash

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

常用Hash函数

MD5
SHA-1
SHA2(SHA2包括了SHA-224、SHA-256、SHA-384,和SHA-512)

Hash的特点

  • 算法是公开的
  • 对相同的数据运算后,得到的结果是一样的
  • 对不同数据运算,如MD5得到的结果默认是128位(0x - 32byte)
  • Hash是不可逆运算
  • 信息摘要,信息“指纹”,用于做数据的识别匹配

因为Hash的算法以及特性,Hash结果有“必然存在,偶然出现”的散列碰撞

Hash的用途

  • 搜索引擎
    • Rabin-Karp字符串搜索算法 是一个相对快速的字符串搜索算法,它所需要的平均搜索时间是O(n).这个算法是创建在使用散列来比较字符串的基础上的。
  • 用户密码的加密
    • 一般服务器不需要知道用户的真是密码,而是通过Hash匹配
    • 如果直接使用MD5加密,容易被反查询
      • 加盐,不使用固定的加盐,提高安全性
      • HMAC加密方案:通过动态Key来加密
      • 加时间戳的方式,灵活,可保证加密结果每次不同,增加时效性。
  • 数字签名
    1. 对传输的原数据进行Hash
    2. 使用RSA加密Hash值(这部分数据就是原始数据的签名信息)
    3. 原始数据+数字签名 一起发送给服务器验证
  • 版权
  • 文件检验【针对文件二进制的hash】

用户密码加密使用

  1. 安全的传递密码信息
  2. 服务器不需要保存用户的真实密码

使用方式/使用弊端

1、直接对密码进行MD5的Hash,容易被散列碰撞库查询出来
2、加盐方式,提高了一定的安全性,但是salt是固定的,一但泄露,就不安全了
3、HMAC加密方案,使用一个Key,并且做了两次散列,实际开发中,Key来自于服务器【相对安全】

针对HMAC加密方案做一个安全流出

  1. 在注册的时候,服务器针对用户生成一个对应的Key
    • 注册时,服务器保存的是用户HMAC加密后的密码
  2. 多设备操作:如果用户在新设备上登录,需要获取登录权限(Key),服务器在接收请求时
    • 如果没有开启权限锁,服务器直接返回用户对应的权限(Key)
    • 如果开启了权限锁,需要已经登录的设备上请求是否给予权限(Key)
  3. 针对第三方截获密码的Hash值
    • 客户端在进行登录操作时,追加服务器的时间戳进行Hash
    • 服务器在检验时,最多进行两次的匹配方式
      例如
      客户端请求 ((HMAC哈希值)+“201910081801”).MD5
      服务器验证 ((HMAC哈希值)+“201910081802”).MD5,如果不匹配再验证((HMAC哈希值)+“201910081801”).MD5【存在59秒的时候发起的请求,服务器接收后时间过了】
    • 这样使得请求的Hash校验有一定的时效安全

对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密

  • 需要对加密和解密使用相同密钥的加密算法。由于其速度快,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。
  • 所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。算法是一组规则,规定如何进行加密和解密。
  • 因此加密的安全性不仅取决于加密算法本身,密钥管理的安全性更是重要。因为加密和解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。

常见算法

常用的单向加密算法:

  1. DES(Data Encryption Standard):数据加密标准,速度较快,适合用于加密大量数据
  2. 3DES(Triple DES):是基于DES,对一块数据用3个不同的密钥进行3次加密,强化了安全性
  3. AES(Advanced Encryption Standard):高级加密标准,速度快,安全级别高,支持128,192,256,512位密钥的加密
算法特征
  1. 加密方和解密方使用同一个密钥;
  2. 加密解密的速度比较快,适合数据比较长时的使用;
  3. 密钥传输的过程不安全,且容易被破解,密钥管理也比较麻烦;

优缺点

优点:算法公开,计算量小,加密速度快,加密效率高

缺点:

  1. 在数据传递钱,发送发和接收方需要商定好密钥,然后保存好密钥。
  2. 如果有一方的密钥泄露,那么信息就不安全了。
  3. 对于安全性,每对用户拥有自己的独立密钥,这使得收发双方会拥有大量的密钥,让管理成为负担。

AES应用

  • ECB(Electronic Code Book):电子密码本模式。
    • 每块数据,独立加密(待处理的信息被分成大小合适的分组,然后分别对每一分组独立进行加密或解密处理)。
    • 这是最基本的加密模式,相同的明文将永远加密成相同的密文,无初始化向量,容易受到密码本重放攻击,一般情况下用于小数据量的字符信息的安全性保护,例如密钥保护。
  • CBC(Cipher Block Chaining):密码分组链接模式。
    • 使用一个密钥和一个初始化向量[IV]对数据进行加密。
    • 明文被加密前要与前面的密文进行异或运算后在加密,因此只要选择不同的初始化向量,相同的明文加密后不会出现相同的密文,是目前使用最广泛的模式。
    • CBC可以有效的保证密文的完整性,如果一块数据块在传递中丢失或者改变,后续的数据将无法正常的解密。

OpenSSL 终端指令

加密

  • AES(ECB)加密字符串
    $ echo -n string | openssl enc - aes-128-ecb -K 616263 -nosalt | base64
  • AES(CBC)加密字符串
    $ echo -n string | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64

解密

  • AES(ECB)解密
    $ echo -n 需要解密的base64 | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
  • AES(CBC)解密
    $ echo -n 需要解密的base64 | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d

CCCrypt函数的使用

  • import <CommonCrypto/CommonCrypto.h>
  • 加密解密的算法都是使用到CCCrypt这个函数
    Parameter:
    CCOperation op > KCCEncrypt加密 / KCCDecrypt 解密
    CCAlgorithm alg > 加密算法【kCCAlgorithm 枚举】
    CCOptions options > 加密选项:ECB/CBC
    const void *key > 加密的密钥
    size_t keyLength > 密钥的长度
    const void *iv > iv 初始化向量
    const void *dataIn > 要被加密的数据
    size_t dataInLength > 要被加密数据的长度
    void *dataOut > 密文的内存地址
    size_t dataOutAvailable > 密文缓冲区的大小
    size_t *dataOutMoved > 解密结果大小
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 设置秘钥
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 设置iv
    uint8_t cIv[self.blockSize];
    bzero(cIv, self.blockSize);
    int option = 0;
    if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else {
        option = kCCOptionPKCS7Padding | kCCOptionECBMode;
    }
    
    // 设置输出缓冲区
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    size_t bufferSize = [data length] + self.blockSize;
    void *buffer = malloc(bufferSize);
    
    // 开始加密
    size_t encryptedSize = 0;
    //加密解密都是它 -- CCCrypt
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          self.algorithm,
                                          option,
                                          cKey,
                                          self.keySize,
                                          cIv,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &encryptedSize);
    
    NSData *result = nil;
    if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    } else {
        free(buffer);
        NSLog(@"[错误] 加密失败|状态编码: %d", cryptStatus);
    }
    
    return [result base64EncodedStringWithOptions:0];
}
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 设置秘钥
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 设置iv
    uint8_t cIv[self.blockSize];
    bzero(cIv, self.blockSize);
    int option = 0;
    if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else {
        option = kCCOptionPKCS7Padding | kCCOptionECBMode;
    }
    
    // 设置输出缓冲区
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
    size_t bufferSize = [data length] + self.blockSize;
    void *buffer = malloc(bufferSize);
    
    // 开始解密
    size_t decryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          self.algorithm,
                                          option,
                                          cKey,
                                          self.keySize,
                                          cIv,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &decryptedSize);
    
    NSData *result = nil;
    if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
    } else {
        free(buffer);
        NSLog(@"[错误] 解密失败|状态编码: %d", cryptStatus);
    }
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容