第一種:明文
有一些APP的登錄注冊(cè)就直接明文,其實(shí)這是十分危險(xiǎn)的指郁,危險(xiǎn)因素多的數(shù)不勝數(shù)忙上。
譬如
- 后臺(tái)被黑客攻破,用戶的所有信息都會(huì)暴露出來(lái)
- 網(wǎng)絡(luò)劫持:劫持之后也可以直接看到我們的明文密碼
- 如果攻擊者破解app闲坎,拿到了沙盒中的數(shù)據(jù)疫粥,也會(huì)造成數(shù)據(jù)泄漏
以前聽(tīng)一個(gè)朋友講他們公司最開(kāi)始的時(shí)候就是用明文進(jìn)行登錄注冊(cè)的,然后有一個(gè)大三的學(xué)生把他們公司的服務(wù)器給攻破了腰懂。辛虧那位學(xué)生并沒(méi)有按什么壞的心眼梗逮,只是把攻破的結(jié)果告訴了他們公司,然后他們公司的程序員一個(gè)兌一兩千塊錢(qián)給了那個(gè)學(xué)生绣溜,算是息事寧人了慷彤。由此可見(jiàn),使用明文登錄注冊(cè)是多么危險(xiǎn)怖喻。其實(shí)現(xiàn)在一般公司都是會(huì)對(duì)數(shù)據(jù)進(jìn)行加密的底哗,除非是那些外包公司做的外包項(xiàng)目,他們實(shí)在是懶得跟你加密锚沸,才回使用明文跋选。
第二種:MD5加密
MD5是一個(gè)安全的散列算法,輸入兩個(gè)不同的明文不會(huì)得到相同的輸出值哗蜈,根據(jù)輸出值前标,不能得到原始的明文坠韩,即其過(guò)程不可逆;所以要解密MD5沒(méi)有現(xiàn)成的算法炼列,只能用窮舉法只搁,把可能出現(xiàn)的明文,用MD5算法散列之后俭尖,把得到的散列值和原始的數(shù)據(jù)形成一個(gè)一對(duì)一的映射表氢惋,通過(guò)比在表中比破解密碼的MD5算法散列值,通過(guò)匹配從映射表中找出破解密碼所對(duì)應(yīng)的原始明文目溉。
MD5有一下四個(gè)特點(diǎn):
- 不可逆的
- 數(shù)量是有限的明肮,可以使用窮舉法破解,MD5破解就是根據(jù)這個(gè)
- MD5算法 不管是什么語(yǔ)言得到的結(jié)果都是一樣的缭付。
- 字符串柿估,圖像,視頻都可以使用MD5加密成32為字符串
蘋(píng)果內(nèi)部用C語(yǔ)言寫(xiě)了MD5加密算法陷猫,但是我們對(duì)只用用C語(yǔ)言來(lái)寫(xiě)的話秫舌,會(huì)感到一點(diǎn)點(diǎn)的麻煩,所以绣檬,網(wǎng)上有很多的人都對(duì)MD5進(jìn)行了一些簡(jiǎn)單的封裝足陨,我這里就隨便摘抄一段
+(NSString *)MD5ForLower32Bate:(NSString *)str{
const char* input = [str UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(input, (CC_LONG)strlen(input), result);
NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[digest appendFormat:@"%02x", result[i]];
}
return digest;
}
我來(lái)對(duì)上一段的代碼進(jìn)行簡(jiǎn)單的分析啊。
const char* input = [str UTF8String];
娇未,進(jìn)行UTF8的轉(zhuǎn)碼墨缘,把字符串類(lèi)型轉(zhuǎn)化為char
類(lèi)型,因?yàn)榧用艿牡讓邮荂語(yǔ)言寫(xiě)的零抬,我們要轉(zhuǎn)化為C語(yǔ)言能看懂的語(yǔ)言镊讼。unsigned char result[CC_MD5_DIGEST_LENGTH];
,設(shè)置一個(gè)接受字符數(shù)組CC_MD5(input, (CC_LONG)strlen(input), result);
,extern unsigned char *CC_MD5(const void *data, CC_LONG len, unsigned char *md)官方封裝好的加密方法平夜。把字符串轉(zhuǎn)換成了32位的16進(jìn)制數(shù)列(這個(gè)過(guò)程不可逆轉(zhuǎn)) 存儲(chǔ)到了result這個(gè)空間中
加密結(jié)果:e10adc3949ba59abbe56e057f20f883e
然后把這個(gè)字符串放到MD5解密網(wǎng)站上
所以蝶棋,單純的MD5對(duì)我們的登錄密碼進(jìn)行加密也不是十分完善的。那些比較懶的用戶可能會(huì)輸入一個(gè)比較簡(jiǎn)單的密碼忽妒,我們也要保護(hù)這部分用戶的密碼不會(huì)被輕易的破解玩裙。這時(shí)候我們就引入了下一個(gè)概念。
第三種:加鹽
普通的MD5加密段直,現(xiàn)在已經(jīng)有軟件可以進(jìn)行破解吃溅,所有我們想出來(lái)一種方法,使MD5這種加密更加復(fù)雜鸯檬,更難被破解罕偎。這種方式就是加鹽(原始密碼 + 鹽) MD5 運(yùn)算.保證密碼不被破解,就要保證鹽值足夠長(zhǎng)/足夠咸
什么是加鹽值
為了加強(qiáng)MD5的安全性(本身是不可逆的),從而加入了新的算法部分即加鹽值京闰,加鹽值是隨機(jī)生成的一組字符串颜及,可以包括隨機(jī)的大小寫(xiě)字母、數(shù)字蹂楣、字符俏站,位數(shù)可以根據(jù)要求而不一樣,使用不同的加鹽值產(chǎn)生的最終密文是不一樣的痊土。
代碼中如何使用加鹽值
由于使用加鹽值以后的密碼相當(dāng)?shù)陌踩拊幢闶悄惬@得了其中的salt和最終密文,破解也是一個(gè)耗費(fèi)相當(dāng)多時(shí)間的過(guò)程赁酝,可以說(shuō)是破解單純MD5的好幾倍犯祠,那么使用加鹽值以后的密文是如何產(chǎn)生的呢?
1).首先我們得到的是明文的hash值
2).進(jìn)行計(jì)算獲取MD5明文hash值
3).隨機(jī)生成加鹽值并插入
4).MD5插入加鹽值得到的hash
5).得到最終的密文
我們就簡(jiǎn)單的使用一下
同樣的字符串123456
在加鹽以后就解密不出來(lái)了
當(dāng)然鹽后臺(tái)傳給我們是最好的酌呆,使用后臺(tái)傳來(lái)的鹽(salt)時(shí)衡载,登錄注冊(cè)我們需要考慮一下邏輯
- 在注冊(cè)時(shí)成功后,后臺(tái)給我們隨機(jī)的返回一個(gè)salt隙袁,并且后臺(tái)使用鹽(salt)md5加密
- 登錄的時(shí)候痰娱,我們用鹽(salt)加密
- 當(dāng)我們更換手機(jī)登錄的時(shí)候,我們向注冊(cè)賬號(hào)發(fā)送登錄請(qǐng)求信息菩收,當(dāng)?shù)卿涃~號(hào)允許新的手機(jī)登錄的時(shí)候梨睁,后臺(tái)給新的手機(jī)發(fā)送以前的salt值(案例:我們跟換微信登錄的時(shí)候,微信會(huì)給我們發(fā)送一個(gè)驗(yàn)證碼娜饵,我們輸入驗(yàn)證碼的過(guò)程就是我們想后臺(tái)請(qǐng)求salt的過(guò)程)
第四種:HMAC加密
其實(shí)上面的思想都有一點(diǎn)HMAC加密的思想坡贺,現(xiàn)在國(guó)外HMAC加密用的十分廣泛了。
HMAC加密算法是一種安全的基于加密hash函數(shù)和共享密鑰的消息認(rèn)證協(xié)議.它可以有效地防止數(shù)據(jù)在傳輸過(guò)程中被截獲和篡改箱舞,維護(hù)了數(shù)據(jù)的完整性遍坟、可靠性和安全性.
HMAC加密算法是一種基于密鑰的報(bào)文完整性的驗(yàn)證方法,其安全性是建立在Hash加密算法基礎(chǔ)上的褐缠。它要求通信雙方共享密鑰政鼠、約定算法、對(duì)報(bào)文進(jìn)行Hash運(yùn)算队魏,形成固定長(zhǎng)度的認(rèn)證碼公般。通信雙方通過(guò)認(rèn)證碼的校驗(yàn)來(lái)確定報(bào)文的合法性。HMAC加密算法可以用來(lái)作加密胡桨、數(shù)字簽名官帘、報(bào)文驗(yàn)證等。
HMAC加密算法的定義
HMAC加密算法是一種執(zhí)行“校驗(yàn)和”的算法昧谊,它通過(guò)對(duì)數(shù)據(jù)進(jìn)行“求和”來(lái)檢查數(shù)據(jù)是否被更改了刽虹。在發(fā)送數(shù)據(jù)以前,HMAC加密算法對(duì)數(shù)據(jù)塊和雙方約定的公鑰進(jìn)行“散列操作”呢诬,以生成稱(chēng)為“摘要”的東西涌哲,附加在待發(fā)送的數(shù)據(jù)塊中胖缤。當(dāng)數(shù)據(jù)和摘要到達(dá)其目的地時(shí),就使用HMAC加密算法來(lái)生成另一個(gè)校驗(yàn)和阀圾,如果兩個(gè)數(shù)字相匹配哪廓,那么數(shù)據(jù)未被做任何篡改。否則初烘,就意味著數(shù)據(jù)在傳輸或存儲(chǔ)過(guò)程中被某些居心叵測(cè)的人作了手腳涡真。
代碼如下:
+ (NSString *)HMacHashWithKey:(NSString *)key data:(NSString *)data{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
//關(guān)鍵部分
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
//將加密結(jié)果進(jìn)行一次BASE64編碼。
NSString *hash = [HMAC base64EncodedStringWithOptions:0];
return hash;
}
其中被加密的字段data肾筐,我們可以設(shè)定一種特殊的生成方式哆料。
加密的密匙key也可以和server端商定一致。
我們做了這些已經(jīng)為保護(hù)用戶賬號(hào)安全做了很多了吗铐,但是东亦,我們還有改進(jìn)的機(jī)會(huì)。
我們知道抓歼,現(xiàn)在用戶經(jīng)常連接公共Wi-Fi讥此,而黑客可以通過(guò)這個(gè)公共Wi-Fi來(lái)獲取我們加密后的密碼以及key,這個(gè)時(shí)候我們還可以添加一層新的防護(hù)
第五種:時(shí)間戳密碼+HMAC
基本介紹
動(dòng)態(tài)密碼:相同的密碼明文+相同的加密算法-->因?yàn)槊看蔚顷憰r(shí)間都不同,所以每次計(jì)算出的結(jié)果也都不相同.可以充分保證密碼的安全性.
服務(wù)器會(huì)計(jì)算兩個(gè)時(shí)間值,當(dāng)期時(shí)間和前一分鐘的時(shí)間(比如:第59S發(fā)送的網(wǎng)絡(luò)請(qǐng)求,一秒鐘后服務(wù)器收到并作出響應(yīng),這時(shí)服務(wù)器當(dāng)前時(shí)間比客戶端發(fā)送時(shí)間晚一分鐘谣妻,仍然能夠判斷準(zhǔn)確的值)
補(bǔ)充介紹:token值
token 值: 登錄令牌.利用 token 值來(lái)判斷用戶的登錄狀態(tài).類(lèi)似于 MD5 加密之后的長(zhǎng)字符串.
用戶登錄成功之后,在后端(服務(wù)器端)會(huì)根據(jù)用戶信息生成一個(gè)唯一的值.這個(gè)值就是 token 值.
基本使用:
在服務(wù)器端(數(shù)據(jù)庫(kù))會(huì)保存這個(gè) token 值,以后利用這個(gè) token 值來(lái)檢索對(duì)應(yīng)的用戶信息,并且判斷用戶的登錄狀態(tài).
用戶登錄成功之后,服務(wù)器會(huì)將生成的 token 值返回給 客戶端,在客戶端也會(huì)保存這個(gè) token 值.(一般可以保存在 cookie 中,也可以自己手動(dòng)確定保存位置(比如偏好設(shè)置.)).
以后客戶端在發(fā)送新的網(wǎng)絡(luò)請(qǐng)求的時(shí)候,會(huì)默認(rèn)自動(dòng)附帶這個(gè) token 值(作為一個(gè)參數(shù)傳遞給服務(wù)器.).服務(wù)器拿到客戶端傳遞的 token 值跟保存在 數(shù)據(jù)庫(kù)中的 token 值做對(duì)比,以此來(lái)判斷用戶身份和登錄狀態(tài).
登錄狀態(tài)判斷
如果客戶端沒(méi)有這個(gè) token 值,意味著沒(méi)有登錄成功過(guò),提示用戶登錄.
如果客戶端有 token 值,一般會(huì)認(rèn)為登錄成功.不需要用戶再次登錄(輸入賬號(hào)和密碼信息).
token 值有失效時(shí)間:
- 一般的 app ,token值得失效時(shí)間都在 1 年以上.
特殊的 app :銀行類(lèi) app /支付類(lèi) app :token值失效時(shí)間 15 分鐘左右. - 一旦用戶信息改變(密碼改變),會(huì)在服務(wù)器生成新的 token 值,原來(lái)的 token值就會(huì)失效.需要再次輸入賬號(hào)和密碼,以得到生成的新的 token 值.
唯一性判斷: 每次登錄,都會(huì)生成一個(gè)新的token值.原來(lái)的 token 值就會(huì)失效.利用時(shí)間來(lái)判斷登錄的差異性.