Swift - 如何實現字符串的HMAC_SHA1加密

1,HMAC(散列消息身份驗證碼:Hashed Message Authentication Code)
它不是散列函數,而是採用了將MD5或SHA1散列函數與共享機密密鑰(與公鑰/私鑰對不一樣)一塊兒使用的消息身份驗證機制。基原本說,消息與密鑰組合並運行散列函數。而後運行結果與密鑰組合並再次運行散列函數。這個128位的結果被截斷成96位,成爲MAC。
 
hmac主要應用在身份驗證中,它的使用方法是這樣的:
1. 客戶端發出登陸請求(假設是瀏覽器的GET請求)
2. 服務器返回一個隨機值,並在會話中記錄這個隨機值
3. 客戶端將該隨機值做爲密鑰,用戶密碼進行hmac運算,而後提交給服務器
4. 服務器讀取用戶數據庫中的用戶密碼和步驟2中發送的隨機值作與客戶端同樣的hmac運算,而後與用戶發送的結果比較,若是結果一致則驗證用戶合法
 
在這個過程當中,可能遭到安全攻擊的是服務器發送的隨機值和用戶發送的hmac結果,而對於截獲了這兩個值的黑客而言這兩個值是沒有意義的,絕無獲取用戶密碼的可能性,隨機值的引入使hmac只在當前會話中有效,大大加強了安全性和實用性。大多數的語言都實現了hmac算法,好比php的mhash、python的hmac.py、java的MessageDigest類,在web驗證中使用hmac也是可行的,用js進行md5運算的速度也是比較快的。
 
2,SHA(安全散列算法:Secure Hash Algorithm)
這個是美國國家標準和技術局發佈的國家標準FIPS PUB 180-1,通常稱爲SHA-1。其對長度不超過264二進制位的消息產生160位的消息摘要輸出,按512比特塊處理其輸入。
SHA是一種數據加密算法,該算法通過加密專家多年來的發展和改進已日益完善,如今已成爲公認的最安全的散列算法之一,並被普遍使用。該算法的思想是接收一段明文,而後以一種不可逆的方式將它轉換成一段(一般更小)密文,也能夠簡單的理解爲取一串輸入碼(稱爲預映射或信息),並把它們轉化爲長度較短、位數固定的輸出序列即散列值(也稱爲信息摘要或信息認證代碼)的過程。散列函數值能夠說時對明文的一種「指紋」或是「摘要」因此對散列值的數字簽名就能夠視爲對此明文的數字簽名。
 
3,HMAC_SHA1(Hashed Message Authentication Code, Secure Hash Algorithm)
這是一種安全的基於加密hash函數和共享密鑰的消息認證協議。它能夠有效地防止數據在傳輸過程當中被截獲和篡改,維護了數據的完整性、可靠性和安全性。HMAC_SHA1消息認證機制的成功在於一個加密的hash函數、一個加密的隨機密鑰和一個安全的密鑰交換機制。
HMAC_SHA1算法在身份驗證和數據完整性方面能夠獲得很好的應用,在目前網絡安全也獲得較好的實現。
 
4,下面演示如何使用Swift進行HMAC_SHA1計算
(1)首先建立橋接頭文件bridge.h來包含須要引用的Objective-C頭文件,並在項目中配置
1
# import  < CommonCrypto / CommonHMAC .h>


(2)下面是一個封裝類,同時對String進行HMAC擴展。(除了SHA1,還可使用其它算法好比MD5,SHA224等)php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//HMAC.swift
import  Foundation
enum  CryptoAlgorithm  {
     case  MD5 SHA1 SHA224 SHA256 SHA384 SHA512
     
     var  HMACAlgorithm CCHmacAlgorithm  {
         var  result:  Int  = 0
         switch  self  {
         case  . MD5 :      result = kCCHmacAlgMD5
         case  . SHA1 :     result = kCCHmacAlgSHA1
         case  . SHA224 :   result = kCCHmacAlgSHA224
         case  . SHA256 :   result = kCCHmacAlgSHA256
         case  . SHA384 :   result = kCCHmacAlgSHA384
         case  . SHA512 :   result = kCCHmacAlgSHA512
         }
         return  CCHmacAlgorithm (result)
     }
     
     var  digestLength:  Int  {
         var  result:  Int32  = 0
         switch  self  {
         case  . MD5 :      result =  CC_MD5_DIGEST_LENGTH
         case  . SHA1 :     result =  CC_SHA1_DIGEST_LENGTH
         case  . SHA224 :   result =  CC_SHA224_DIGEST_LENGTH
         case  . SHA256 :   result =  CC_SHA256_DIGEST_LENGTH
         case  . SHA384 :   result =  CC_SHA384_DIGEST_LENGTH
         case  . SHA512 :   result =  CC_SHA512_DIGEST_LENGTH
         }
         return  Int (result)
     }
}
 
extension  String  {
     func  hmac(algorithm:  CryptoAlgorithm , key:  String ) ->  String  {
         let  str =  self .cStringUsingEncoding( NSUTF8StringEncoding )
         let  strLen =  Int ( self .lengthOfBytesUsingEncoding( NSUTF8StringEncoding ))
         let  digestLen = algorithm.digestLength
         let  result =  UnsafeMutablePointer < CUnsignedChar >.alloc(digestLen)
         let  keyStr = key.cStringUsingEncoding( NSUTF8StringEncoding )
         let  keyLen =  Int (key.lengthOfBytesUsingEncoding( NSUTF8StringEncoding ))
         
         CCHmac (algorithm. HMACAlgorithm , keyStr!, keyLen, str!, strLen, result)
         
         let  digest = stringFromResult(result, length: digestLen)
         
         result.dealloc(digestLen)
         
         return  digest
     }
     
     private  func  stringFromResult(result:  UnsafeMutablePointer < CUnsignedChar >, length:  Int ) ->  String  {
         let  hash =  NSMutableString ()
         for  in  0..<length {
             hash.appendFormat( "%02x" , result[i])
         }
         return  String (hash)
     }
}


(3)測試樣例html

1
2
3
4
5
6
7
8
9
10
11
12
13
let  str =  "welcome to hangge.com"
let  key =  "67FG"
let  hmacStr = str.hmac(. SHA1 , key: key)
         
print ( "原始字符串:\(str)" )
print ( "key:\(key)" )
print ( "HMAC運算結果:\(hmacStr)" )
         
/**** 輸出 ******
原始字符串:welcome to hangge.com
key:67FG
HMAC運算結果:79a5f5b138b5646289a9648de035c80e9c5c14c7
*****/


原文出自:www.hangge.com  轉載請保留原文連接:http://www.hangge.com/blog/cache/detail_851.htmljava

相關文章
相關標籤/搜索