平時開發中不只會遇到各類須要保護用戶隱私的狀況,並且還有可能須要對公司核心數據進行保護,這時候加密隱私數據就成爲了必要。然而市場上存在着各類各樣的抓包工具及解密算法,甚至一些公司有專門的逆向部門,這就加大了數據安全的風險,本文將經過如下幾個方面對各類加密算法進行分析對比:php
一般咱們對消息進行加解密有兩種處理方式:css
因爲咱們可能對各類各樣的數據進行加密,好比:視頻、音頻、文本文件等,因此加密以前咱們須要統一文件類型,而後再進行加密處理。git
// 要編碼的字符串
NSString *str = @"haha";
// 轉換成二進制文件
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
// 進行base64編碼
NSString *dataStr = [data base64EncodedStringWithOptions:kNilOptions];
NSLog(@"%@", dataStr);複製代碼
// 先對數據進行解碼
NSData *encData = [[NSData alloc]initWithBase64EncodedString:dataStr options:kNilOptions];
// 將二進制數據轉換成字符串
NSString *encStr = [[NSString alloc]initWithData:encData encoding:NSUTF8StringEncoding];
NSLog(@"%@", encStr);複製代碼
接下來分析一下Base64的編碼過程,參考維基百科:github
若是要編碼的字節數不能被3整除,最後會多出1個或2個字節,那麼可使用下面的方法進行處理:先使用0字節值在末尾補足,使其可以被3整除,而後再進行Base64的編碼。在編碼後的Base64文本後加上一個或兩個=號,表明補足的字節數。也就是說,當最後剩餘兩個八位字節(2個byte)時,最後一個6位的Base64字節塊有四位是0值,最後附加上兩個等號;若是最後剩餘一個八位字節(1個byte)時,最後一個6位的base字節塊有兩位是0值,最後附加一個等號。 參考下表:算法
若原數據長度不是3的倍數時且剩下1個輸入數據,則在編碼結果後加2個=;若剩下2個輸入數據,則在編碼結果後加1個=數據庫
如上面的例子:瀏覽器
原數據爲A
,數據長度爲1,1 % 3 = 1 後面加兩個==安全
原數據爲bc
,數據長度爲2,2 % 3 = 2 後面加一個=服務器
單向散列函數也稱爲消息摘要函數、哈希函數或者雜湊函數。
單向散列函數輸出的散列值又稱爲消息摘要或者指紋微信
特色:
經典算法:
安全性:
疑問一:單項散列函數爲何不可逆??
原來好多同窗知識知道md5加密是不可逆的,殊不知道是爲何,其實散列函數能夠將任意長度的輸入通過變化獲得不一樣的輸出,若是存在兩個不一樣的輸入獲得了相同的散列值,咱們稱之爲這是一個碰撞,由於使用的hash
算法,在計算過程當中原文的部分信息是丟失了的,一個MD5理論上能夠對應多個原文,由於MD5是有限多個,而原文是無限多個的。
網上看到一個形象的例子:2 + 5 = 7,可是根據 7 的結果,卻並不能推算出是由 2 + 5計算得來的
疑問二:爲何有些網站能夠解密MD5後的數據??
MD5解密網站,並非對加密後的數據進行解密,而是數據庫中存在大量的加密後的數據,對用戶輸入的數據進行匹配(也叫暴力碰撞),匹配到與之對應的數據就會輸出,並無對應的解密算法。
由以上信息能夠知道,MD5加密後的數據也並非特別安全的,其實並無絕對的安全策略,咱們能夠對MD5進行改進,加大破解的難度,典型的加大解密難度的方式有一下幾種:
也能夠進行屢次的md5運算,總之就是要加大破解的難度。
原理:
使用:
對稱加密的特色:
經典算法:
密碼算法能夠分爲分組密碼和流密碼兩種:
分組模式:主要有兩種
某一塊分組被修改,不影響後面的加密結果
CBC模式(又稱電子密碼鏈條)
iv
某一塊分組被修改,影響後面的加密結果
加密:
/** * 加密字符串並返回base64編碼字符串 * * @param string 要加密的字符串 * @param keyString 加密密鑰 * @param iv 初始化向量(8個字節) * * @return 返回加密後的base64編碼字符串 */
NSLog(@"%@", [[EncryptionTools sharedEncryptionTools] encryptString:@"haha" keyString:@"abc" iv:nil]);
// 輸出 MIoAu+xUEpQZSUmkZUW6JQ==複製代碼
解密:
NSLog(@"%@", [[EncryptionTools sharedEncryptionTools] decryptString:@"MIoAu+xUEpQZSUmkZUW6JQ==" keyString:@"abc" iv:nil]);
// 輸出 haha複製代碼
加密:
uint8_t iv[8] = {1,2,3,4,5,6,7,8};
NSData *data = [[NSData alloc] initWithBytes:iv length:sizeof(iv)];
NSLog(@"%@", [[EncryptionTools sharedEncryptionTools] encryptString:@"haha" keyString:@"abc" iv:data]);
// 輸出 E/wWqUTiw/E+1DThAzV39A==複製代碼
解密:
NSLog(@"%@", [[EncryptionTools sharedEncryptionTools] decryptString:@"E/wWqUTiw/E+1DThAzV39A==" keyString:@"abc" iv:data]);
// 輸出 haha複製代碼
對稱加密存在的問題??
很明顯,對稱加密主要取決於祕鑰的安全性,數據傳輸的過程當中,若是祕鑰被別人破解的話,之後的加解密就將失去意義
其實有點兒相似於咱們日常看的諜戰類的電視劇,地下黨將情報發送給後方,一般須要一箇中間人將密碼本傳輸給後方,若是中間人被抓交出密碼本,那麼未來全部的情報都將失去意義,因而可知情報工做多麼的重要!!!
對稱密碼體制中只有一種密鑰,而且是非公開的,若是要解密就得讓對方知道密鑰。因此保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就能夠不須要像對稱密碼那樣傳輸對方的密鑰了
鑑於對稱加密存在的風險,非對稱加密應運而生
特色:
非對稱密碼體制的特色:算法強度複雜、安全性依賴於算法與密鑰,可是因爲其算法複雜,而使得加密解密速度沒有對稱加密解密的速度快
經典算法:
* 求N,準備兩個質數p和q,N = p x q
* 求L,L是p-1和q-1的最小公倍數。L = lcm(p-1,q-1)
* 求E,E和L的最大公約數爲1(E和L互質)
* 求D,E x D mode L = 1複製代碼
* p = 17,q = 19 =>N = 323
* lcm(p-1,q-1)=>lcm(16,18)=>L= 144
* gcd(E,L)=1 =>E=5
* E乘以幾能夠mode L =1? D=29能夠知足
* 獲得公鑰爲:E=5,N=323
* 獲得私鑰爲:D=29,N=323
* 加密 明文的E次方 mod N = 123的5次方 mod 323 = 225(密文)
* 解密 密文的D次方 mod N = 225的29次方 mod 323 = 123(明文)複製代碼
原理上看非對稱加密很是安全,客戶端用公鑰進行加密,服務端用私鑰進行解密,數據傳輸的只是公鑰,原則上看,就算公鑰被人截獲,也沒有什麼用,由於公鑰只是用來加密的,那還存在什麼問題呢??那就是經典的中間人攻擊
廢了半天勁畫的圖,太low了,我仍是本身總結一遍吧!!!
中間人攻擊詳細步驟:
疑問一:爲何會形成中間人攻擊??
形成中間人攻擊的直接緣由就是客戶端沒辦法判斷公鑰信息的正確性。
疑問二:怎麼解決中間人攻擊??
須要對公鑰進行數字簽名。就像古代書信傳遞,家人之因此知道這封信是你寫的,是由於信上有你的簽名、印章等證實你身份的信息。
數字簽名須要嚴格驗證發送發的身份信息!!!
數字證書包含:
數字證書能夠本身生成,也能夠從權威機構購買,可是注意,本身生成的證書,只能本身承認,別人都不承認.
權威機構簽名的證書:
以GitHub官網爲例,Chrome瀏覽器打開網址,地址欄有一個小綠鎖,點擊,內容以下:
能夠看到鏈接是安全的,點擊證書能夠看到詳細信息
這是由權威機構認證的證書,可是是須要花錢的,一年至少得一兩千,因此也有些公司用本身簽名的證書,本身簽名的證書不被信任,可能會提示用戶有風險,好比原來的12306網站,如今大多數網站也都採用了CA簽名數字證書進行簽名,本身作簽名的也很差找了!!!12306都改爲CA認證的了。。。
openssl genrsa -out private.pem 1024複製代碼
openssl req -new -key private.pem -out rsacert.csr複製代碼
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt複製代碼
openssl x509 -outform der -in rsacert.crt -out rsacert.der複製代碼
openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt複製代碼
注意:
代碼演示:
// p12 是私鑰
// .der 是公鑰
// 非對稱加密,使用公鑰加密,私鑰解密
// 加載公鑰
[[RSACryptor sharedRSACryptor] loadPublicKey:[[NSBundle mainBundle] pathForResource:@"rsacert.der" ofType:nil]];
// 對數據加密
NSData *data = [[RSACryptor sharedRSACryptor] encryptData:[@"hahaha" dataUsingEncoding:NSUTF8StringEncoding]];
// 對加密獲得的密文進行base64編碼打印
NSLog(@"%@", [data base64EncodedStringWithOptions:kNilOptions]);
// 輸出結果:PflhCgTVNegcQXrb39RJOoxCRRIHuZ3LN0/hoxTDFBbC+8yKjp0m+/hxVUWBVsTo28WnNFCAFfrQ2of5SkqttD51a5eLb21R7bQSQRxg/gVZ5hePcE3vh7Slfcxm2qJM+J8hRWDP/MF4BiDLXI9ZqTpLCSS5mjJtmUBf2wNvI1Y=
// 私鑰解密
// 加載私鑰
[[RSACryptor sharedRSACryptor] loadPrivateKey:[[NSBundle mainBundle] pathForResource:@"p.p12" ofType:nil] password:@"123456"];
// 解密
NSData *decryDeta = [[RSACryptor sharedRSACryptor] decryptData:data];
NSLog(@"%@", [[NSString alloc] initWithData:decryDeta encoding:NSUTF8StringEncoding]);
// 輸出:hahaha複製代碼
至此數據安全和加解密相關結算完畢,寫博客的過程,也是學習的過程,斷斷續續的寫了三四天,總算寫完了,同時也對原來一些模糊的概念有了更清晰的認識,寫的這篇文章看了文頂頂老師的視頻,受益不淺,十分感謝,最近學習發現,學的越多,感受會的越少,時間十分的不夠用。同時渴望遇到一些但願進步、不甘平凡的同行!!!共勉!!!
小編這呢,給你們推薦一個優秀的iOS交流平臺,平臺裏的夥伴們都是很是優秀的iOS開發人員,咱們專一於技術的分享與技巧的交流,你們能夠在平臺上討論技術,交流學習。歡迎你們的加入(想要進入的可加小編微信)。 13142121176