程序員面試閃充--iOS密碼學

但凡一個有點追求的iOS開發,總得會點加密技術,要不然用戶信息就有可能被其他人獲取用來做一些對我們不利的事情。

一、base64

base64是一種完全可反編譯的編碼方式,因為編碼算法完全公開,所以分分鐘就會被破解,所以這個一定不能用于密碼的“加密”,一些不需要特別加密的,例如用戶名,我們可以用base64進行編碼,讓人不是一眼就能看出來是什么。

Base64 是網絡上最常見的用于傳輸8Bit 字節代碼的編碼方式之一,Base64 要求把每三個8Bit 的字節轉換為四個6Bit 的字節(38 = 46 = 24 ),然后把6Bit 再添兩個高位0 ,組成四個8Bit 的字節,也就是說,轉換后的字符串理論上將要比原來的長1/3 。

比如說:

轉換前 aaaaaabb ccccdddd eeffffff

轉換后 00aaaaaa 00bbcccc 00ddddee 00ffffff

上面的三個字節是原文,下面的四個字節是轉換后的Base64 編碼,其前兩位均為0。

轉換后,我們用一個碼表來得到我們想要的字符串(也就是最終的Base64 編碼),這個表是這樣的:

字符 值字符 值字符 值字符 值0 A17 R34 i51 z1 B18 S35 j52 02 C19 T36 k53 13 D20 U37 l54 24 E21 V38 m55 35 F22 W39 n56 46 G23 X40 o57 57 H24 Y41 p58 68 I25 Z42 q59 79 J26 a43 r60 810 K27 b44 s61 911 L28 c45 t62 +12 M29 d46 u63 /13 N30 e47 v=14 O31 f48 w

15 p32 g49 x

16 Q33 h50 y

讓我們再來看一個實際的例子,加深印象!

轉換前 10101101 10111010 01110110

轉換后 00101011 00011011 00101001 00110110

在用二進制表示的字符串前面補0得到轉換后的字符串,再對應十進制的碼表就能得到最后的結果啦

十進制 43 27 41 54

對應碼表中的值是rbp2

可是等等…… 好像有疑惑,原文的字節數量應該是3 的倍數啊,如果這個條件不能滿足的話,那該怎么辦呢?

其實可以這樣解決:原文的字節不夠的地方可以用全0 來補足,轉換時Base64 編碼用= 號來代替。這就是為什么有些Base64 編碼會以一個或兩個等號結束的原因,但等號最多只有兩個。因為:

余數 = 原文字節數 MOD 3

所以余數任何情況下都只可能是0 ,1 ,2 這三個數中的一個。如果余數是0 的話,就表示原文字節數正好是3的倍數。如果是1 的話,為了讓Base64 編碼是4的倍數,就要補2個等號;同理,如果是2 的話,就要補1 個等號。

以 Hello!! 為例,其轉換過程為:

圖中藍色背景的二進制的0值是額外補充的。Hello!! Base64編碼的結果為 SGVsbG8hIQAA 。最后2個零值只是為了Base64編碼而補充的,在原始字符中并沒有對應的字符,那么Base64編碼結果中的最后兩個字符 AA 實際不帶有效信息,所以需要特殊處理,以免解碼錯誤。

標準Base64編碼通常用 = 字符來替換最后的 A,即編碼結果為 SGVsbG8hIQ==。因為 = 字符并不在Base64編碼索引表中,其意義在于結束符號,在Base64解碼時遇到 = 時即可知道一個Base64編碼字符串結束。

- (NSString *)base64EncodedString;

{NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];return [data base64EncodedStringWithOptions:0];

}

- (NSString *)base64DecodedString

{NSData *data = [[NSData alloc]initWithBase64EncodedString:self options:0];return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

}

二、MD5

全稱是Message Digest Algorithm 5,譯為“消息摘要算法第5版”。它能對輸入信息生成唯一的128位散列值(32個字符)。輸入兩個不同的明文不會得到相同的輸出值,根據輸出值,不能得到原始的明文,即其過程不可逆。

由于MD5加密算法具有較好的安全性,而且免費,因此該加密算法被廣泛使用。主要運用在數字簽名、文件完整性驗證以及口令加密等方面。

當用戶進行注冊、登錄操作時,我們可以直接對密碼進行MD5操作,用戶Login的時候,系統是把用戶輸入的密碼計算成MD5值,然后再去和系統中保存的MD5值進行比較,而系統并"不知道"用戶的密碼是什么。

MD5特點:

壓縮性 : 任意長度的數據,算出的MD5值長度都是固定的。

容易計算 : 從原數據計算出MD5值很容易。

抗修改性 : 對原數據進行任何改動,哪怕只修改一個字節,所得到的MD5值都有很大區別。

弱抗碰撞 : 已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。

強抗碰撞 : 想找到兩個不同數據,使他們具有相同的MD5值,是非常困難的。

/****************************MD5.m類實現文件內容****************************///對字符串數據進行MD5的簽名+ (NSString *)md5SignWithString:(NSString *)string

{? ? const char *object = [string UTF8String];? ? unsigned char result[CC_MD5_DIGEST_LENGTH];

CC_MD5(object,(CC_LONG)strlen(object),result);? ? NSMutableString *hash = [NSMutableString string];? ? for (int i = 0; i < 16; i ++) {

[hash appendFormat:@"X", result[i]];

}? ? return [hash lowercaseString];

}//對二進制數據進行MD5的簽名+ (NSData *)md5SignWithData:(NSData *)data

{

Byte byte[CC_MD5_DIGEST_LENGTH];? ? //定義一個字節數組來接收結果

CC_MD5((const void*)([data bytes]), (CC_LONG)[data length], byte);? ? return [NSData dataWithBytes:byte length:CC_MD5_DIGEST_LENGTH];

}/******************************************************************************///使用MD5文件進行MD5加密和驗簽/*********************************使用MD5類*********************************///使用MD5執行加密操作NSString *string2 = @"abcdefghijklmnopqrstuvwxyz";NSString *encodeString2 = [MD5 md5SignWithString:string2];NSLog(@"encodeString2 : %@", encodeString2);//MD5為不可逆的操作,使用MD5執行驗簽操作NSString *verifyString2 = [MD5 md5SignWithString:string2];NSLog(@"verifyString2 : %@", verifyString2);if ([verifyString2 isEqualToString:encodeString2]) {? ? NSLog(@"md5 verify sign success");

} else {? ? NSLog(@"md5 verify sign failed");

}

然而現在的MD5已不再是絕對安全,因為網上有一套數據庫可以查到許多MD5的詞條。對此,可以對MD5稍作改進,以增加解密的難度。

加鹽(Salt):在明文的固定位置插入隨機串,然后再進行MD5

先加密,后亂序:先對明文進行MD5,然后對加密得到的MD5串的字符進行亂序??傊谥季褪牵汉诳途退愎テ屏藬祿?,也無法解密出正確的明文。

三、HMAC加密

此加密方法需要先生成密鑰,然后再對密碼進行MD5和HMAC加密,數據庫中需要存放當時使用的密鑰和密碼加密后的密文

在用戶登陸時 再次對填入的密碼用密鑰進行加密 并且還要加上當前時間(精確到分鐘) 再次HMAC加密,服務器里也會拿出以前存放的密文加上時間再次加密。所以就算黑客在中途截取了密碼的密文 也在能在1分鐘只能破譯才能有效,大大加強了安全性。服務器為了考慮到網絡的延遲一般會多算一種答案,如23分過來的密碼 他會把23分和22分的都算一下和用戶匹配只要對上一個就允許登陸。

四、AES加密

高級加密標準Advanced Encryption Standard簡稱:AES。是美國聯邦政府采用的一種區塊加密標準。AES設計有三個密鑰長度:128、192、256位,相對而言,AES的128密鑰比DES的56密鑰強1021倍。AES算法主要包括三個方面:輪變化、圈數和密鑰擴展。

AES加解密特點:

AES強安全性、高性能、高效率、易用和靈活。

在軟件及硬件上都能快速地加解密且只需要很少的存儲資源。

AES的使用:除了類庫本身只有Config類里面包含AESCrpt.h,只有兩個方法用到。一個是保存用戶名和密碼,密碼使用了AES加密,另一個是解密密碼后再返回這個密碼;保存用戶名和密碼是將用戶名和密碼放到了本地的一個沙盒之中,獲取的時候直接從本地讀取加密后的文件,經過解密和服務器上用戶數據進行比較。

-(void)saveUserNameAndPwd:(NSString *)userName andPwd:(NSString *)pwd?

{?

NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];?

[settings removeObjectForKey:@"UserName"];?

[settings removeObjectForKey:@"Password"];?

[settings setObject:userName forKey:@"UserName"];?

pwd = [AESCrypt encrypt:pwd password:@"pwd"];?

[settings setObject:pwd forKey:@"Password"];?

[settings synchronize];?

}?

-(NSString *)getPwd?

{?

NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];?

NSString * temp = [settings objectForKey:@"Password"];?

return [AESCrypt decrypt:temp password:@"pwd"];?

}

正如官方給出示例用法一樣,AES的使用非常簡單,首先要添加頭文件 #import "AESCrypt.h",使用示例如下:

NSString *pwdKey = @"新風作浪";?

NSString *password = @"duxinfeng123456";?

NSString *encryptedPWD = [AESCrypt encrypt:password password:pwdKey];?

NSString *decryptedPWD = [AESCrypt decrypt:encryptedPWD password:pwdKey];?

NSLog(@"加密后密碼:%@? 解密后密碼: %@",encryptedPWD,decryptedPWD);

五、RSA加密

RSA非對稱加密算法

非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)

公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那么只有用對應的公開密鑰才能解密

特點:

非對稱密碼體制的特點:算法強度復雜、安全性依賴于算法與密鑰但是由于其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快

對稱密碼體制中只有一種密鑰,并且是非公開的,如果要解密就得讓對方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就可以不需要像對稱密碼那樣傳輸對方的密鑰了。

基本加密原理:

(1)找出兩個“很大”的質數:P & Q

(2)N = P * Q

(3)M = (P – 1) * (Q – 1)

(4)找出整數E,E與M互質,即除了1之外,沒有其他公約數

(5)找出整數D,使得E*D除以M余1,即 (E * D) % M = 1

經過上述準備工作之后,可以得到:

E是公鑰,負責加密

D是私鑰,負責解密

N負責公鑰和私鑰之間的聯系

加密算法,假定對X進行加密

(X ^ E) % N = Y

n根據費爾馬小定義,根據以下公式可以完成解密操作

(Y ^ D) % N = X

但是RSA加密算法效率較差,對大型數據加密時間很長,一般用于小數據。

六、指紋識別

指紋識別功能是 iphone 5S之后推出的.SDK是 iOS 8.0 推出,它的出現簡化移動支付環節,迅速占領了移動支付市場。

使用步驟:

導入框架

#import

獲得當前系統版本號

```float version = [UIDevice currentDevice].systemVersion.floatValue;if (version < 8.0 ) // 判斷當前系統版本 {

NSLog(@"系統版本太低,請升級至最新系統");? ? return;

}

實例化指紋識別對象,判斷當前設備是否支持指紋識別功能(是否帶有TouchID)

// 1> 實例化指紋識別對象? ? LAContext *laCtx = [[LAContext alloc] init];? ? // 2> 判斷當前設備是否支持指紋識別功能.? ? if (![laCtx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:NULL]) {? ? ? ? // 如果設備不支持指紋識別功能? ? ? ? NSLog(@"該設備不支持指紋識別功能");? ? ? ? return;? ? };

指紋登錄(默認是異步方法)

[laCtx evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"指紋登陸" reply:^(BOOL success, NSError *error) {? ? ? ? // 如果成功,表示指紋輸入正確.? ? ? ? if (success) {? ? ? ? ? ? NSLog(@"指紋識別成功!");? ? ? ? } else {? ? ? ? ? ? NSLog(@"指紋識別錯誤,請再次嘗試");? ? ? ? }? ? }];

七、面試題

1、你會如何存儲用戶的一些敏感信息,如登錄的token?

使用keychain來存儲,也就是鑰匙串,使用keychain需要導入Security框架

iOS的keychain服務提供了一種安全的保存私密信息(密碼,序列號,證書等)的方式,每個ios程序都有一個獨立的keychain存儲。相對于 NSUserDefaults、文件保存等一般方式,keychain保存更為安全,而且keychain里保存的信息不會因App被刪除而丟失,所以在 重裝App后,keychain里的數據還能使用。從ios 3。0開始,跨程序分享keychain變得可行。

如何需要在應用里使 用使用keyChain,需要導入Security.framework ,keychain的操作接口聲明在頭文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要寫的代碼較為復雜,可以使用一些已經封裝好了的工具類KeychainItemWrapper和 SFHFKeychainUtils。

2、說說你加密算法常用在什么地方?

遠程推送:用戶設備與蘋果的APNS服務器形成長連接時,蘋果服務器會加密生成一個deviceToken給用戶設備。

對信息保密:將明文通過接收人的公鑰加密,傳輸給接受人時使用非對稱算法可以防止中間人攻擊。

身份驗證和防止篡改

登錄注冊

支付寶支付

3、OSI七層模型中,哪一層用于數據格式轉化和數據加密呢?(B)

A、應用層 B、表示層? C、會話層 D 傳輸層

解釋: 表示層提供各種用于應用層數據的編碼和轉換功能,確保一個系統的應用層發送的數據能被另一個系統的應用層識別。如果必要,該層可提供一種標準表示形式,用于將計算機內部的多種數據格式轉換成通信中采用的標準表示形式。數據壓縮和加密也是表示層可提供的轉換功能之一。

4、逆向分析最常用的有三種方法是什么?

網絡分析

通過分析和篡改接口數據,可以有效的破解通過接口數據來控制客戶端行為的app,常用的抓包工具有Tcpdump, WireShark, Charles等,windows平臺有fidller

靜態分析

通過砸殼、反匯編、classdump頭文件等技術來分析app行為,通過這種方式可以有效的分析出app實用的一些第三方庫,甚至分析出app的架構等內容,常用的工具有dumpdecrypted(砸殼)、hopper disassembler(反匯編)、class_dump(導頭文件)

動態分析

動態分析指的是通過分析app的運行時數據,來定位注入點或者獲取關鍵數據,常用的工具有cycript(運行時控制臺)、 lldb+debugserver(遠程斷點調試)、logify(追蹤)

5、(阿里三面)怎樣防止反編譯?

1.本地數據加密

iOS應用防反編譯加密技術之一:對NSUserDefaults,sqlite存儲文件數據加密,保護帳號和關鍵信息

2.URL編碼加密

iOS應用防反編譯加密技術之二:對程序中出現的URL進行編碼加密,防止URL被靜態分析

3.網絡傳輸數據加密

iOS應用防反編譯加密技術之三:對客戶端傳輸數據提供加密方案,有效防止通過網絡接口的攔截獲取數據

4.方法體,方法名高級混淆

iOS應用防反編譯加密技術之四:對應用程序的方法名和方法體進行混淆,保證源碼被逆向后無法解析代碼

5.程序結構混排加密

iOS應用防反編譯加密技術之五:對應用程序邏輯結構進行打亂混排,保證源碼可讀性降到最低

6.借助第三方APP加固

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • 但凡一個有點追求的iOS開發,總得會點加密技術,要不然用戶信息就有可能被其他人獲取用來做一些對我們不利的事情。 視...
    謙謙君子修羅刀閱讀 1,531評論 1 41
  • /**ios常見的幾種加密方法: 普通的加密方法是講密碼進行加密后保存到用戶偏好設置( [NSUserDefaul...
    彬至睢陽閱讀 2,960評論 0 7
  • 怎么說呢 十分惆悵的記錄著自己的生活。我不知道現在的生活究竟怎么樣 唯一的感覺就是累 說什么做什么都要斟酌 哦 不...
    愛是左溢呀閱讀 257評論 0 0
  • 關于炎癥與海馬萎縮的思考 老師,第二次看這篇文章。只能說,它是從宏觀上簡化了的炎癥解釋。 一句話概括,炎癥是身體的...
    湯云程閱讀 122評論 0 0
  • 背景 周末參加topgeek組織的2016年度中國架構師大會,日程之一是圓桌會議:“如何成為頂級架構師”。有意思的...
    ruben肖三漁閱讀 1,860評論 0 1