密碼學之Hash與對稱加密算法

密碼學之RSA加密算法 中,咱們瞭解了 非對稱加密算法 (典型的表明是 RSA算法)的基本原理,而且使用終端簡單地體驗了一下RSA算法的操做流程。而 Hash算法對稱加密算法 也是現代密碼學體系中的重要組成部分。接下來,咱們將一一介紹下它們。算法

1. Hash(散列函數)

1.1 什麼是Hash?

Hash,通常翻譯作散列、哈希,是把任意長度的輸入經過Hash算法變成固定長度的輸出,該輸出就是Hash值(哈希值,或散列值)。這種轉換是一種壓縮映射,也就是,哈希值的空間一般遠小於輸入的空間,不一樣的輸入可能會Hash成相同的輸出。簡單的說Hash就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數安全

Hash算法也被稱爲散列算法、哈希算法,雖然被稱爲算法,但實際上它更像是一種思想。Hash算法沒有一個固定的公式,只要符合Hash思想的算法均可以被稱爲是Hash算法。bash

1.2 哈希碰撞

因爲Hash是無限集的數據向有限集的單方向映射,因此不免會出現:對不一樣的數據可能獲得相同的Hash值,這種現象稱爲 哈希碰撞,或稱 散列碰撞。以下圖所示:服務器

黑客攻擊的一種方法,就是設法制造【哈希碰撞】,從而破解用戶的密碼,竊取用戶的信息。併發

X個二進制位的Hash值,產生碰撞的可能性是 2X 分之一。如函數

16個二進制位的Hash值,產生碰撞的可能性是 65536 分之一;
32個二進制位的Hash值,產生碰撞的可能性是 4,294,967,296 分之一。post

因而可知,有效地防止哈希碰撞的方法,就是 擴大Hash值的取值空間。固然,更長的哈希值意味着更大的存儲空間、更多的計算,這將影響性能和成本。實際應用中,開發者必須作出抉擇,在安全與成本之間找到平衡。性能

1.3 Hash函數的性質

全部Hash函數都有一個基本特性:若是兩個哈希值是不相同的(根據同一函數),那麼這兩個哈希值的原始輸入也是不相同的。這個特性是散列函數具備肯定性的結果。反之則否則,即 若是兩個哈希值相同,兩個輸入值極可能是相同的,但不絕對確定兩者必定相等(可能出現哈希碰撞)網站

Hash函數還有如下一些特色:ui

  • 算法是公開的,且很難找到逆向規律,即無法進行逆運算。
  • 若是輸入數據相同,那麼通過同一Hash函數輸出值必然相同。

Hash函數能使對一個數據序列的訪問過程更加迅速有效,經過Hash函數,數據元素將被更快地定位。

1.4 常見Hash的算法及應用

說到Hash,就不得不提到一些著名的Hash算法。在衆多Hash算法中,MD五、SHA一、SHA256能夠說是應用最普遍的了,而它們都是以MD4爲基礎設計的。下面簡單介紹一下這幾個Hash算法:

  • MD4

MD4是MIT的 Ronald L. Rivest 在1990年設計的,MD是Message Digest(消息摘要)的縮寫。它是基於32位操做數的位操做來實現的。

  • MD5

MD5是 Rivest 於1991年對MD4的改進版本。MD5比MD4複雜,速度要慢一點,但更安全,在抗分析和抗差分方面表現更好。

  • SHA1

SHA1是由 NIST NSA 設計爲同DSA一塊兒使用的,它對長度小於2^64的輸入,產生長度爲160bit的Hash值,所以抗窮舉性更好。但在相同的硬件上,SHA1較MD5會稍慢一些。

  • SHA256

SHA256是SHA1的後繼者,對於任意長度的消息,SHA256都會產生一個256位長的Hash值。與SHA1相比,SHA256的抗窮舉性更好,但速度則慢一些。

Hash算法普遍應用於 錯誤校訂語音識別信息安全 中,其在信息安全的應用主要體如今如下幾個方面:

  • 文件校驗

即校驗文件是否被篡改。

  • 數字簽名

因爲非對稱算法的運算速度較慢,因此在數字簽名協議中,先對文件進行運算獲得其Hash值(其Hash值又被稱爲【數字摘要】),而後對數字摘要進行數字簽名,在統計上認爲與對文件自己進行數字簽名是等效的。

  • 鑑權協議

以下的鑑權協議又被稱做挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的狀況下,這是一種簡單而安全的方法。

注意:

Hash算法加密的對象是 文件的二進制內容,只要文件的二進制內容沒發生改變,其Hash值不變。

如,假設有一張文件名爲【001.png】的圖片,更名爲【002.txt】,比較其更名先後md5值是否發生改變;將其壓縮後,再試試看

2. Hash示例:密碼加密

在實際運用中,服務器是不會保存用戶密碼的,從安全角度考慮,App不會有【找回密碼】功能,有的只是【重置密碼】。那麼,用戶註冊時,客戶端發給服務器的密碼是怎樣的呢?

接下來,咱們以MD5加密算法爲例,探討一下對密碼進行怎樣的處理才能使其足夠安全。

  1. 對密碼進行一次 MD5算法加密(假設密碼是【123456】)

思考:直接將【e10adc3949ba59abbe56e057f20f883e】做爲【密碼】發給服務器能夠嗎?

因爲Hash的特色:對相同數據的Hash運算,獲得的結果是同樣的。所以,只要有足夠多的這種明文密文對應關係的數據,利用窮舉字符組合的方式,是能夠反向查詢到原始數據的。實際上,提供這種服務的網站有不少。這裏向你們介紹一個做者本身經常使用的:MD5在線加密解密。接下來反向查詢一下:

顯然,【對密碼進行一次MD5算法加密】在安全上仍然是不足的。

這裏可能會有讀者有疑問,只要用戶將密碼設置得足夠複雜(多種類型字符混排之類),應該就不會這麼簡單被反向查詢到吧。的確如此,可是密碼的安全不該該寄但願於用戶的【自主行爲】。

  1. 給密碼加鹽
    給密碼加鹽的目的是讓密碼複雜一些。具體作法是,寫個全局的靜態常量salt,將其與密碼拼接起來,使密碼看上去複雜一些,而後再進行MD5加密。如salt="sdfSD_FHja%(s"。(此時密碼爲【sdfSD_FHja%(s123456】)

一樣,對其反向查詢一下

看來,加鹽的作法使密碼相對安全了。

思考,【鹽】泄露了怎麼辦?

  1. HMAC加密方案
    此方案利用Hash算法,以一個消息M和一個密鑰K做爲輸入,生成其Hash值。

密鑰K是隨機選取的(每一個用戶的密鑰K都是隨機值),能夠採用一種強僞隨機發生器,而且密鑰須要週期性更新。

當用戶註冊時,將原始密碼進行上述【1】或【2】處理後,發給服務器,服務器爲該用戶生成一個密鑰K,將其發給客戶端的同時,對用戶密碼和密鑰K再進行MD5運算。客戶端會將密鑰K保存到本地,之後每次登陸都對密碼通過HMAC加密方案處理後,再將結果發給服務器校驗。代碼以下:

static NSString *salt = @"sdfSD_FHja%(";

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSString *pwd = @"123456";
    pwd = [salt stringByAppendingString:pwd].md5String;
    NSLog(@"加鹽後的密碼是:%@", pwd);
    
    // 假設本地保存的密鑰K爲"Um7f1ltAibSF!$w@8"
    NSString *key = @"Um7f1ltAibSF!$w@8";
    pwd = [pwd hmacMD5StringWithKey:key];
    NSLog(@"如今的密碼是:%@", pwd);
}
複製代碼

其結果爲

反查詢一下

從上面的流程不難看出, HMAC加密方案 使密碼與設備(用戶註冊時的設備)進行了綁定(其它設備無密鑰K)。其它設備想登陸此帳號時,向服務器請求獲取密鑰K,服務器會檢測用戶是否開啓了設備鎖,若是開啓了,就通知受權設備請求受權,受權經過後纔會將密鑰K發給其它設備。顯然,HMAC加密方案相對【1】、【2】的處理,更加安全了。

注意:

思考:上述對密碼的三種處理,均將最終密碼發送給服務器,這樣作有沒有什麼隱患?

  1. 對密碼進行有效時間處理

即在請求登陸以前,能夠向服務器請求最新時間(如201910230836,精確到分),再進行相似這樣的處理:(HMAC哈希值+"201910230836").md5,將其發送給服務器,服務器再進行校驗,若是密碼有效期小於2分鐘,則先校驗當前時間下的值(假設過了1分鐘):
(HMAC哈希值+"201910230837").md5
若是不匹配,再校驗前1分鐘的值:
(HMAC哈希值+"201910230836").md5

毫無疑問,在這種機制下,客戶端登陸的密碼具備時效性,其有效時間越短安全性越強。

3. 數字簽名

接下來談一談Hash在信息安全上的應用。設想一個這樣的場景:

假設你要買一件10塊錢的商品,你在客戶端將訂單信息發送給服務端,請求支付;
黑客竊取了你的訂單信息,並將金額改爲20元,而後發送給服務端;
服務端扣了你20元,同時生成消費信息,併發送給你;
黑客竊取了消費信息,又將金額改爲10元,繼續發送給你;
你收到了這10元的消費信息。

在這個過程當中,黑客神不知鬼不覺地篡改了你提交的信息,形成了你的損失。那麼該如何保護你的信息的完整性呢?這就要用到數字簽名技術了。

3.1 什麼是數字簽名

數字簽名(又稱公鑰數字簽名)是隻有信息的發送者才能產生的別人沒法僞造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證實。它是一種相似寫在紙上的普通的物理簽名,可是使用了公鑰加密領域的技術來實現的,用於鑑別數字信息的方法。一套數字簽名一般定義兩種互補的運算,一個用於簽名,另外一個用於驗證。數字簽名是 非對稱密鑰加密技術數字摘要技術 的應用。

  1. 關於非對稱加密算法的介紹,不熟悉的同窗請移步 密碼學之RSA加密算法
  2. 數字摘要是將任意長度的消息變成固定長度的短消息。是否是很熟悉?其實就是Hash。數字摘要就是採用Hash算法將【明文】輸出爲一串固定長度(如128位)的密文,這一串密文又稱爲數字指紋。

3.2 數字簽名流程

通常來講,非對稱加密是用來處理短消息的,而相對於較長的消息則顯得有些吃力。固然,能夠將長的消息分紅若干小段,而後再分別簽名。不過,這樣作很是麻煩,並且會帶來數據完整性的問題。比較合理的作法是在 數字簽名前對消息先進行數字摘要

一樣是上述的場景,結合數字簽名技術以後,其流程以下:

  1. 當你發起10元的支付訂單信息時,客戶端用Hash算法(如MD五、SHA1等)將此訂單信息加密生成【數字摘要】,同時用服務端的 公鑰 對數字摘要進行加密,這個加密後的摘要也就是【數字簽名】;
  2. 客戶端將【訂單信息】和【數字簽名】一塊兒發給服務端;
  3. 服務端收到後,用 私鑰 解析數字簽名,獲得【數字摘要1】,同時,再對【訂單信息】用一樣的Hash算法(約定好的)加密生成【數字摘要2】,進而匹配數字摘要1和數字摘要2:若是一致,說明訂單信息是完整真實的,能夠進行扣款;不然說明訂單信息被篡改,訂單無效。

數字簽名是個加密的過程,數字簽名驗證是個解密的過程。

PS. 咱們使用的支付寶,其支付過程就使用了數字簽名技術進行安全驗證。

總結:數字簽名有兩種功效

  1. 能肯定消息確實是由發送方簽名併發出來的,由於別人假冒不了發送方的簽名。
  2. 能肯定消息的完整性。由於數字簽名的特色是它表明了文件的特徵,文件若是發生改變,數字摘要的值也將發生變化。

4. 對稱加密

4.1 什麼是對稱加密

使用相同的密鑰對信息進行加密和解密,這種加密方式叫作 對稱加密。也就是說,就是明文經過密鑰加密獲得密文,密文經過密鑰加密獲得明文。

讓咱們簡單比較一下 非對稱加密Hash對稱加密

  • 非對稱加密用於加密少許數據,加密效率低,可是很是安全。
  • Hash用於信息識別,驗證信息的真僞和完整性
  • 對稱加密用於加密大量數據,加密速度快、效率高,可是一旦密鑰泄露,密文將毫無安全性可言。

4.2 經常使用的對稱加密算法

經常使用的對稱加密算法有

  • DES:是數據加密標準,比較典型,可是如今用得少。

特色:強度小、速度較快,

  • 3DES:是基於DES,對一塊數據用三個不一樣的密鑰進行三次加密。

特色:強度較DES高一些,速度也快。可是三個密鑰不便於管理,所以用得也少。

  • AES:高級加密標準,被普通使用。

特色:速度快,安全級別高;
PS. 蘋果的鑰匙串訪問、美國國家安全局等都是用AES。若是你想玩對稱加密,也建議用AES。

4.3 對稱加密算法的應用模式

主要有兩種應用模式,即ECB和CBC。

  • ECB:電子密碼本模式。每一塊數據,獨立加密。

最基本的加密模式,也就是一般理解的加密,相同的明文將永遠加密成相同的密文,無初始向量,容易受到密碼本重放攻擊,通常狀況下不多用。

  • CBC:密碼分組連接模式。使用一個密鑰和一個**初始化向量[IV]**對數據執行加密。
  1. 明文被加密前要與前面的密文進行異或運算後再加密,所以只要選擇不一樣的初始向量,相同的密文加密後會造成不一樣的密文,這是目前應用最普遍的模式。
  2. CBC能夠有效的保證密文的完整性,若是一個數據塊在傳遞是丟失或改變,後面的數據將沒法正常解密。
  3. 它的主要缺點在於加密過程是串行的,沒法被並行化,並且消息必須被填充到塊大小的整數倍。
  4. 常應用於防竊聽技術中。

4.4 對稱加密算法示例:

接下來,咱們用終端來玩一玩對稱加密算法。操做流程以下:

  1. 準備明文文件(message.txt)

  1. 對明文進行 AES(ECB)加密
  • 生成密文文件(msg1.bin)
openssl enc -aes-128-ecb -K 616263 -nosalt -in message.txt -out msg1.bin
複製代碼

參數說明:

  1. enc:表示是對稱加密
  2. -K:密鑰K值爲616263(其實是abc,即0x610x620x63)
  3. -nosalt:不加鹽(openssl會隨機加鹽,此處不須要)
  4. -out:加密後的密文輸出到msg1.bin文件中
  • 修改明文內容(如將第二行的第二個數字1改爲a),再進行 AES(ECB)加密,生成密文文件(msg2.bin)

  • 對比一下 msg1.bin 和 msg2.bin

顯而後面的數據塊並不受到前面數據塊內容改變的影響,充分說明ECB模式是每一塊數據進行獨立加密。

  1. 還原明文文件,對明文進行 AES(CBC)加密
  • 生成密文文件(msg3.bin)
openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out msg3.bin
複製代碼

參數說明:

  1. -iv:初始化向量值爲0102030405060708(隨機取的)
  • 修改明文內容,再進行 AES(CBC)加密,生成密文文件(msg4.bin)

  • 對比一下 msg3.bin 和 msg4.bin

顯而後面的數據塊受到了前面數據塊內容改變的影響,充分說明了CBC能夠有效的保證密文的完整性,即若是一個數據塊在傳遞是丟失或改變,後面的數據將沒法正常解密。

參考資料

相關文章
相關標籤/搜索