網絡安全——Base64編碼、MD五、SHA1-SHA5十二、HMAC(SHA1-SHA512)哈希

網絡安全——Base64編碼、MD五、SHA1-SHA5十二、HMAC(SHA1-SHA512)哈希

 

聽說今天520是個好日子,爲何我想起的是50二、500、404這些?還好服務器沒事!ios

1、Base64編碼

Base64編碼要求把3個8位字節(3*8=24)轉化爲4個6位的字節(4*6=24),以後在6位的前面補兩個0,造成8位一個字節的形式,這樣每個字節的有效位爲6位,則取值範圍0~630 ~ (2^6 - 1)。若是最後剩下的字符不到3個字節,則用0填充,輸出字符使用'=',所以咱們看到Base64末尾會有1到2個'='。另外標準還要求每76個字符要插入換行(不過,這個視具體狀況定)。nginx

iOS7以後蘋果有本身的Base64編碼解碼API,NSData的擴展:NSData (NSDataBase64Encoding)git

兩種存儲方式

  • 可見字符串形式

爲了保證所輸出的每個編碼字節都是可讀字符,而不是0~63這些數字,Base64製做了一個碼錶,就像ASCII碼錶同樣,每個Base64碼值都有對應的字符。64個可讀字符從0到63非別是A-Z、a-z、0-九、+、/,這也是Base64名字的由來。github

  • 以16進制形式

即NSData形式保存,Base64編碼結果爲字符,而這些字符又對應ASCII碼錶的碼值,NSData就是存儲ASCII碼錶的碼值。api

下面舉個例子,並以蘋果提供的API來詳細介紹Base64編碼解碼過程:

假設咱們對字符串"123"進行Base64編碼,"123"對應的16進制是313233,二進制爲0011000一、001100十、00110011,將其變爲4*6結果即下表中的第一行。而後根據Base64的碼錶,它們分別對應表中的第二行。那麼"123"編碼的最終結果即爲MTIz,以字符串的形式保存。而後根據MTIz對應ASCII碼值,以NSData形式存儲,如表中的第三行。安全

轉換爲4*6結果 00001100 00010011 00001000 00110011
Base64對應字符 M T I z
對應ASCII碼值(16進制) 4d 54 49 7a

上面的過程經過代碼實現以下:服務器

// 1 待編碼的原始字符串 NSString *plainStr = @"123"; // 2 將其轉換成NSData保存,那麼"123"對應的ASCII碼錶碼值是3一、3二、33(16進制) NSData *plainData = [plainStr dataUsingEncoding:NSUTF8StringEncoding]; // 3.1 將其進行Base64編碼,且結果以字符串形式保存,對應表中的第二行 NSString *baseStr = [plainData base64EncodedStringWithOptions:0]; // 3.2 將其進行Base64編碼,且結果以NSData形式保存 NSData *base64Data = [plainData base64EncodedDataWithOptions:0];

另外對於參數NSDataBase64EncodingOptions選項,有多種取值markdown

  • NSDataBase64Encoding64CharacterLineLength:每64個字符插入\r或\n
  • NSDataBase64Encoding76CharacterLineLength:每76個字符插入\r或\n,標準中有要求是76個字符要換行,不過具體仍是本身定
  • NSDataBase64EncodingEndLineWithCarriageReturn:插入字符爲\r
  • NSDataBase64EncodingEndLineWithLineFeed:插入字符爲\n

前兩個選項爲是否容許插入字符,以及多少個字符長度插入,兩個能夠選其一或者都不選。後兩個選項表明要插入的具體字符。好比咱們想76個字符後插入一個\r則能夠NSDataBase64Encoding76CharacterLineLength | NSDataBase64EncodingEndLineWithCarriageReturn。而在上面舉的例子中選項爲0,則表明不插入字符。網絡

第三方框架

在iOS7以前咱們通常用的都是第三方框架,好比nicklockwood寫的https://github.com/nicklockwood/Base64還有Google的GTMBase64,雖然蘋果有了本身的實現,可是許多其它的加密框架都用到了它,因此仍是要了解一下,另外它還提供任意長度字符插入\r\n,而蘋果只能是64或76長度。

2、MD五、SHA一、SHA25六、SHA5十二、HMAC實現

主要用於驗證,防止信息被修改。介紹請參照http://www.jianshu.com/p/003b85fd3e36

具體的實現參考第三方框架:https://github.com/kelp404/CocoaSecurity。很是全面,不過不是太方便,好比想要得到MD5結果

NSString *plainStr = @"123"; CocoaSecurityResult *md5 = [CocoaSecurity md5:plainStr]; // 獲取md5結果 NSString *md5Str = md5.hexLower;

不能直接plainStr.MD5Hash就得到字符串形式的結果,這裏我封裝了一個,能夠參見工程中的NSString+Hash類https://github.com/mddios/EncryptionTools,能夠直接對字符串進行操做,相似plainStr.MD5Hash、plainStr.sha1Hash···plainStr.sha256Hash···,很是方便。

好比對@"123"哈希,下面用上面提到的兩種方法舉例:

- (void)hashTest { NSString *plainStr = @"123"; // md5 CocoaSecurityResult *md5 = [CocoaSecurity md5:plainStr]; NSLog(@"md5:%lu---%@---%@",plainStr.md5Hash.length, plainStr.md5Hash,md5.hex); // 40 CocoaSecurityResult *sha1 = [CocoaSecurity sha1:plainStr]; NSLog(@"sha1:%lu---%@---%@",plainStr.sha1Hash.length, plainStr.sha1Hash,sha1.hex); // 56 CocoaSecurityResult *sha224 = [CocoaSecurity sha224:plainStr]; NSLog(@"sha224:%lu---%@---%@",plainStr.sha224Hash.length,plainStr.sha224Hash,sha224.hex); // 64 CocoaSecurityResult *sha256 = [CocoaSecurity sha256:plainStr]; NSLog(@"sha256:%lu---%@---%@",plainStr.sha256Hash.length,plainStr.sha256Hash,sha256.hex); // 96 CocoaSecurityResult *sha384 = [CocoaSecurity sha384:plainStr]; NSLog(@"sha384:%lu---%@---%@",plainStr.sha384Hash.length,plainStr.sha384Hash,sha384.hex); // 128 CocoaSecurityResult *sha512 = [CocoaSecurity sha512:plainStr]; NSLog(@"sha512:%lu---%@---%@",plainStr.sha512Hash.length,plainStr.sha512Hash,sha512.hex); // hmac CocoaSecurityResult *hmacmd5 = [CocoaSecurity hmacMd5:plainStr hmacKey:plainStr]; NSLog(@"hmacmd5:%lu---%@---%@",[plainStr hmacMD5WithKey:plainStr].length,[plainStr hmacMD5WithKey:plainStr],hmacmd5.hex); }
  • 在電腦終端來獲取結果

封裝的代碼中NSString+Hash.h頭文件,有具體列出終端命令方法,以下:

/// 返回結果:32長度 終端命令:md5 -s "123" - (NSString *)md5Hash; /// 返回結果:40長度 終端命令:echo -n "123" | openssl sha -sha1 - (NSString *)sha1Hash; /// 返回結果:56長度 終端命令:echo -n "123" | openssl sha -sha224 - (NSString *)sha224Hash; /// 返回結果:64長度 終端命令:echo -n "123" | openssl sha -sha256 - (NSString *)sha256Hash; /// 返回結果:96長度 終端命令:echo -n "123" | openssl sha -sha384 - (NSString *)sha384Hash; /// 返回結果:128長度 終端命令:echo -n "123" | openssl sha -sha512 - (NSString *)sha512Hash; #pragma mark - HMAC /// 返回結果:32長度 終端命令:echo -n "123" | openssl dgst -md5 -hmac "123" - (NSString *)hmacMD5WithKey:(NSString *)key; /// 返回結果:40長度 echo -n "123" | openssl sha -sha1 -hmac "123" - (NSString *)hmacSHA1WithKey:(NSString *)key; - (NSString *)hmacSHA224WithKey:(NSString *)key; - (NSString *)hmacSHA256WithKey:(NSString *)key; - (NSString *)hmacSHA384WithKey:(NSString *)key; - (NSString *)hmacSHA512WithKey:(NSString *)key;
  • 關於MD5加鹽,只是多了下面第一行
plainStr = [plainStr stringByAppendingString:salt]; NSString *md5Str = plainStr.md5Hash;

github代碼下載地址

https://github.com/mddios/EncryptionTools

相關文章
相關標籤/搜索