Hash和對(duì)稱加密

Hash

Hash,一般翻譯做散列、雜湊晚缩,或音譯為哈希,是把任意長度的輸入(又叫做預(yù)映射pre-image)通過散列算法變換成固定長度的輸出媳危,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射冈敛,也就是待笑,散列值的空間通常遠(yuǎn)小于輸入的空間,不同的輸入可能會(huì)散列成相同的輸出抓谴,所以不可能從散列值來確定唯一的輸入值暮蹂。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)寞缝。

常用Hash函數(shù)

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

Hash的特點(diǎn)

  • 算法是公開的
  • 對(duì)相同的數(shù)據(jù)運(yùn)算后,得到的結(jié)果是一樣的
  • 對(duì)不同數(shù)據(jù)運(yùn)算集侯,如MD5得到的結(jié)果默認(rèn)是128位(0x - 32byte)
  • Hash是不可逆運(yùn)算
  • 信息摘要被啼,信息“指紋”,用于做數(shù)據(jù)的識(shí)別匹配

因?yàn)镠ash的算法以及特性棠枉,Hash結(jié)果有“必然存在浓体,偶然出現(xiàn)”的散列碰撞

Hash的用途

  • 搜索引擎
    • Rabin-Karp字符串搜索算法 是一個(gè)相對(duì)快速的字符串搜索算法,它所需要的平均搜索時(shí)間是O(n).這個(gè)算法是創(chuàng)建在使用散列來比較字符串的基礎(chǔ)上的辈讶。
  • 用戶密碼的加密
    • 一般服務(wù)器不需要知道用戶的真是密碼命浴,而是通過Hash匹配
    • 如果直接使用MD5加密,容易被反查詢
      • 加鹽贱除,不使用固定的加鹽生闲,提高安全性
      • HMAC加密方案:通過動(dòng)態(tài)Key來加密
      • 加時(shí)間戳的方式,靈活月幌,可保證加密結(jié)果每次不同碍讯,增加時(shí)效性。
  • 數(shù)字簽名
    1. 對(duì)傳輸?shù)脑瓟?shù)據(jù)進(jìn)行Hash
    2. 使用RSA加密Hash值(這部分?jǐn)?shù)據(jù)就是原始數(shù)據(jù)的簽名信息)
    3. 原始數(shù)據(jù)+數(shù)字簽名 一起發(fā)送給服務(wù)器驗(yàn)證
  • 版權(quán)
  • 文件檢驗(yàn)【針對(duì)文件二進(jìn)制的hash】

用戶密碼加密使用

  1. 安全的傳遞密碼信息
  2. 服務(wù)器不需要保存用戶的真實(shí)密碼

使用方式/使用弊端

1飞醉、直接對(duì)密碼進(jìn)行MD5的Hash冲茸,容易被散列碰撞庫查詢出來
2、加鹽方式缅帘,提高了一定的安全性轴术,但是salt是固定的,一但泄露钦无,就不安全了
3逗栽、HMAC加密方案,使用一個(gè)Key失暂,并且做了兩次散列彼宠,實(shí)際開發(fā)中,Key來自于服務(wù)器【相對(duì)安全】

針對(duì)HMAC加密方案做一個(gè)安全流出

  1. 在注冊的時(shí)候弟塞,服務(wù)器針對(duì)用戶生成一個(gè)對(duì)應(yīng)的Key
    • 注冊時(shí)凭峡,服務(wù)器保存的是用戶HMAC加密后的密碼
  2. 多設(shè)備操作:如果用戶在新設(shè)備上登錄,需要獲取登錄權(quán)限(Key)决记,服務(wù)器在接收請(qǐng)求時(shí)
    • 如果沒有開啟權(quán)限鎖摧冀,服務(wù)器直接返回用戶對(duì)應(yīng)的權(quán)限(Key)
    • 如果開啟了權(quán)限鎖,需要已經(jīng)登錄的設(shè)備上請(qǐng)求是否給予權(quán)限(Key)
  3. 針對(duì)第三方截獲密碼的Hash值
    • 客戶端在進(jìn)行登錄操作時(shí),追加服務(wù)器的時(shí)間戳進(jìn)行Hash
    • 服務(wù)器在檢驗(yàn)時(shí)索昂,最多進(jìn)行兩次的匹配方式
      例如
      客戶端請(qǐng)求 ((HMAC哈希值)+“201910081801”).MD5
      服務(wù)器驗(yàn)證 ((HMAC哈希值)+“201910081802”).MD5建车,如果不匹配再驗(yàn)證((HMAC哈希值)+“201910081801”).MD5【存在59秒的時(shí)候發(fā)起的請(qǐng)求,服務(wù)器接收后時(shí)間過了】
    • 這樣使得請(qǐng)求的Hash校驗(yàn)有一定的時(shí)效安全

對(duì)稱加密

采用單鑰密碼系統(tǒng)的加密方法椒惨,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密缤至,這種加密方法稱為對(duì)稱加密,也稱為單密鑰加密康谆。

  • 需要對(duì)加密和解密使用相同密鑰的加密算法领斥。由于其速度快,對(duì)稱性加密通常在消息發(fā)送方需要加密大量數(shù)據(jù)時(shí)使用秉宿。對(duì)稱性加密也稱為密鑰加密戒突。
  • 所謂對(duì)稱,就是采用這種加密方法的雙方使用方式用同樣的密鑰進(jìn)行加密和解密描睦。密鑰是控制加密及解密過程的指令膊存。算法是一組規(guī)則,規(guī)定如何進(jìn)行加密和解密忱叭。
  • 因此加密的安全性不僅取決于加密算法本身隔崎,密鑰管理的安全性更是重要。因?yàn)榧用芎徒饷芏际褂猛粋€(gè)密鑰韵丑,如何把密鑰安全地傳遞到解密者手上就成了必須要解決的問題爵卒。

常見算法

常用的單向加密算法:

  1. DES(Data Encryption Standard):數(shù)據(jù)加密標(biāo)準(zhǔn),速度較快撵彻,適合用于加密大量數(shù)據(jù)
  2. 3DES(Triple DES):是基于DES钓株,對(duì)一塊數(shù)據(jù)用3個(gè)不同的密鑰進(jìn)行3次加密,強(qiáng)化了安全性
  3. AES(Advanced Encryption Standard):高級(jí)加密標(biāo)準(zhǔn)陌僵,速度快轴合,安全級(jí)別高,支持128碗短,192受葛,256,512位密鑰的加密
算法特征
  1. 加密方和解密方使用同一個(gè)密鑰偎谁;
  2. 加密解密的速度比較快总滩,適合數(shù)據(jù)比較長時(shí)的使用;
  3. 密鑰傳輸?shù)倪^程不安全巡雨,且容易被破解闰渔,密鑰管理也比較麻煩;

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):算法公開铐望,計(jì)算量小澜建,加密速度快向挖,加密效率高

缺點(diǎn):

  1. 在數(shù)據(jù)傳遞錢蝌以,發(fā)送發(fā)和接收方需要商定好密鑰炕舵,然后保存好密鑰。
  2. 如果有一方的密鑰泄露跟畅,那么信息就不安全了咽筋。
  3. 對(duì)于安全性,每對(duì)用戶擁有自己的獨(dú)立密鑰徊件,這使得收發(fā)雙方會(huì)擁有大量的密鑰奸攻,讓管理成為負(fù)擔(dān)。

AES應(yīng)用

  • ECB(Electronic Code Book):電子密碼本模式虱痕。
    • 每塊數(shù)據(jù)睹耐,獨(dú)立加密(待處理的信息被分成大小合適的分組,然后分別對(duì)每一分組獨(dú)立進(jìn)行加密或解密處理)部翘。
    • 這是最基本的加密模式硝训,相同的明文將永遠(yuǎn)加密成相同的密文,無初始化向量新思,容易受到密碼本重放攻擊窖梁,一般情況下用于小數(shù)據(jù)量的字符信息的安全性保護(hù),例如密鑰保護(hù)夹囚。
  • CBC(Cipher Block Chaining):密碼分組鏈接模式纵刘。
    • 使用一個(gè)密鑰和一個(gè)初始化向量[IV]對(duì)數(shù)據(jù)進(jìn)行加密。
    • 明文被加密前要與前面的密文進(jìn)行異或運(yùn)算后在加密荸哟,因此只要選擇不同的初始化向量假哎,相同的明文加密后不會(huì)出現(xiàn)相同的密文,是目前使用最廣泛的模式鞍历。
    • CBC可以有效的保證密文的完整性舵抹,如果一塊數(shù)據(jù)塊在傳遞中丟失或者改變,后續(xù)的數(shù)據(jù)將無法正常的解密堰燎。

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函數(shù)的使用

  • import <CommonCrypto/CommonCrypto.h>
  • 加密解密的算法都是使用到CCCrypt這個(gè)函數(shù)
    Parameter:
    CCOperation op > KCCEncrypt加密 / KCCDecrypt 解密
    CCAlgorithm alg > 加密算法【kCCAlgorithm 枚舉】
    CCOptions options > 加密選項(xiàng):ECB/CBC
    const void *key > 加密的密鑰
    size_t keyLength > 密鑰的長度
    const void *iv > iv 初始化向量
    const void *dataIn > 要被加密的數(shù)據(jù)
    size_t dataInLength > 要被加密數(shù)據(jù)的長度
    void *dataOut > 密文的內(nèi)存地址
    size_t dataOutAvailable > 密文緩沖區(qū)的大小
    size_t *dataOutMoved > 解密結(jié)果大小
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 設(shè)置秘鑰
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 設(shè)置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;
    }
    
    // 設(shè)置輸出緩沖區(qū)
    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(@"[錯(cuò)誤] 加密失敗|狀態(tài)編碼: %d", cryptStatus);
    }
    
    return [result base64EncodedStringWithOptions:0];
}
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 設(shè)置秘鑰
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 設(shè)置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;
    }
    
    // 設(shè)置輸出緩沖區(qū)
    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(@"[錯(cuò)誤] 解密失敗|狀態(tài)編碼: %d", cryptStatus);
    }
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掏父,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秆剪,更是在濱河造成了極大的恐慌赊淑,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仅讽,死亡現(xiàn)場離奇詭異陶缺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)洁灵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門饱岸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掺出,“玉大人,你說我怎么就攤上這事苫费√老牵” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵百框,是天一觀的道長闲礼。 經(jīng)常有香客問我,道長铐维,這世上最難降的妖魔是什么柬泽? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嫁蛇,結(jié)果婚禮上锨并,老公的妹妹穿的比我還像新娘。我一直安慰自己睬棚,他們只是感情好第煮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闸拿,像睡著了一般空盼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上新荤,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天揽趾,我揣著相機(jī)與錄音,去河邊找鬼苛骨。 笑死篱瞎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的痒芝。 我是一名探鬼主播俐筋,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼严衬!你這毒婦竟也來了澄者?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤请琳,失蹤者是張志新(化名)和其女友劉穎粱挡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俄精,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡询筏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竖慧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫌套。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逆屡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出踱讨,到底是詐尸還是另有隱情魏蔗,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布勇蝙,位于F島的核電站沫勿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏味混。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一诫惭、第九天 我趴在偏房一處隱蔽的房頂上張望翁锡。 院中可真熱鬧,春花似錦夕土、人聲如沸馆衔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽角溃。三九已至,卻和暖如春篮撑,著一層夾襖步出監(jiān)牢的瞬間减细,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工赢笨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留未蝌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓茧妒,卻偏偏與公主長得像萧吠,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桐筏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容