/-------------------------------01 保存用戶信息 -------------------------------------/
重點(diǎn):1.偏好設(shè)置保存用戶信息.
{
<1>如果用戶登陸成功,就保存用戶信息.下次直接從偏好設(shè)置中讀取用戶信息,以此做到用戶只需要輸入一次賬號(hào)和密碼,以后登陸就可以不用再次輸入.
1>.登陸成功,保存用戶信息(偏好設(shè)置)
2>.再次進(jìn)入,直接顯示用戶之前保存的信息.避免用戶重復(fù)輸入.
// 偏好設(shè)置存儲(chǔ)用戶信息
-(void)savaUserInfo
{
// 實(shí)例化偏好設(shè)置對(duì)象(單例)
NSUserDefaults *User = [NSUserDefaults standardUserDefaults];
// 保存用戶名
[User setObject:self.userName.text forKey:kITUSERNAMEKEY];
// 保存用戶密碼
[User setObject:pass forKey:kITUSERPASSKEY];
// 同步保存用戶信息
[User synchronize];
}
// 加載偏好設(shè)置中的用戶信息
- (void)loadUserInfo
{
NSUserDefaults *User = [NSUserDefaults standardUserDefaults];
if ([User objectForKey:ITUSERNAMEKEY]) {
self.userName.text = [User objectForKey:ITUSERNAMEKEY];
}if ([User objectForKey:ITUSERPASSKEY]) {
self.password.text = [User objectForKey:ITUSERPASSKEY];
};
}
<2> 用戶登陸業(yè)務(wù)邏輯
{
// <1> 用戶登陸需要一個(gè)單獨(dú)的控制器,因?yàn)橹恍枰顷懸淮?Login.storyboard). 應(yīng)用程序需要有一個(gè)入口:main.storyboard: app 主頁(yè)面
// <2> 判斷用戶是否登陸成功過(guò)(通過(guò)偏好設(shè)置中存儲(chǔ)的用戶信息判斷)
// 1> 如果偏好設(shè)置中存有用戶信息(說(shuō)明之前登陸成功過(guò)),直接進(jìn)入 app 主頁(yè)面 :main.storyboard
// 2> 如果偏好設(shè)置中不存在用戶信息(第一次登陸或者之前注銷了用戶信息),進(jìn)入登陸界面 :Login.storyboard
// <3> 如果用戶登陸成功,跳轉(zhuǎn)到 app 主頁(yè)面:main.storyboard.并且在偏好設(shè)置中保存用戶信息.
// <4> 如果用戶點(diǎn)擊注銷按鈕,注銷用戶信息,返回到登陸頁(yè)面.
}
<3> 問(wèn)題: 用戶密碼不能以明文的形式保存,需要對(duì)用戶密碼加密之后再保存!
密碼的安全原則:
1> 本地和服務(wù)器都不允許保存用戶的密碼明文.
2> 在網(wǎng)絡(luò)上,不允許傳輸用戶的密碼明文.
現(xiàn)代密碼學(xué)趣聞! 中途島海戰(zhàn)(AF)
<4> 數(shù)據(jù)加密算法:
1> 對(duì)稱加密算法:加密和解密使用同一密鑰.加密解密速度快,要保證密鑰安全.適合給大數(shù)據(jù)加密.
2> 非對(duì)稱加密算法:使用公鑰加密,私鑰解密.或者使用私鑰加密,公鑰解密.更加安全,但是加密解密速度慢,適合給小數(shù)據(jù)加密.
<5> 小技巧:
openssl :是一個(gè)強(qiáng)大的安全套接字層密碼庫(kù),囊括主要的密碼算法,常用的密鑰和證書封裝管理功能以及 SSL 協(xié)議.提供豐富的應(yīng)用程序測(cè)試功能.
終端命令:
echo hello |openssl md5
echo hello |openssl sha1
echo hello |openssl sha -sha256
echo hello |openssl sha -sha512
}
/---------------------------- 02 信息安全加密 -------------------------------------/
了解:常用加密方法: 1> base64 2> MD5 3> MD5加鹽 4> HMAC 5> 時(shí)間戳密碼(用戶密碼動(dòng)態(tài)變化)
{
1> base64
{
base64 編碼是現(xiàn)代密碼學(xué)的基礎(chǔ).
原本是 8個(gè)bit 一組表示數(shù)據(jù),改為 6個(gè)bit一組表示數(shù)據(jù),不足的部分補(bǔ)零,每 兩個(gè)0 用 一個(gè) = 表示.
用base64 編碼之后,數(shù)據(jù)長(zhǎng)度會(huì)變大,增加了大約 1/3 左右.
base64 基本能夠達(dá)到安全要求,但是,base64能夠逆運(yùn)算,非常不安全!
base64 編碼有個(gè)非常顯著的特點(diǎn),末尾有個(gè) '=' 號(hào).
利用終端命令進(jìn)行base64運(yùn)算:
// 將文件 meinv.jpg 進(jìn)行 base64運(yùn)算之后存儲(chǔ)為 meinv.txt
base64 meinv.jpg -o meinv.txt
// 講meinv.txt 解碼生成 meinv.png
base64 -D meinv.txt -o meinv.png
// 將字符串 "hello" 進(jìn)行 base 64 編碼 結(jié)果:aGVsbG8=
echo "hello" | base64
// 將 base64編碼之后的結(jié)果 aGVsbG8= 反編碼為字符串
echo aGVsbG8= | base64 -D
}
2> MD5 -- (信息-摘要算法) 哈希算法之一.
{
把一個(gè)任意長(zhǎng)度的字節(jié)串變換成一定長(zhǎng)度的十六進(jìn)制的大整數(shù). 注意,字符串的轉(zhuǎn)換過(guò)程是不可逆的.
用于確保'信息傳輸'完整一致.
MD5特點(diǎn):
*1.壓縮性: 任意長(zhǎng)度的數(shù)據(jù),算出的 MD5 值長(zhǎng)度都是固定的.
*2.容易計(jì)算: 從原數(shù)據(jù)計(jì)算出 MD5 值很容易.
*3.抗修改性: 對(duì)原數(shù)據(jù)進(jìn)行任何改動(dòng),哪怕只修改一個(gè)字節(jié),所得到的 MD5 值都有很大區(qū)別.
*4.弱抗碰撞: 已知原數(shù)據(jù)和其 MD5 值,想找到一個(gè)具有相同 MD5 值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的.
*5.強(qiáng)抗碰撞: 想找到兩個(gè)不同數(shù)據(jù),使他們具有相同的 MD5 值,是非常困難的.
MD5 應(yīng)用:
*1. 一致性驗(yàn)證: MD5 將整個(gè)文件當(dāng)做一個(gè)大文本信息,通過(guò)不可逆的字符串變換算法,產(chǎn)生一個(gè)唯一的 MD5 信息摘要.就像每個(gè)人都有自己獨(dú)一無(wú)二的指紋,MD5 對(duì)任何文件產(chǎn)生一個(gè)獨(dú)一無(wú)二的"數(shù)字指紋".
利用 MD5 來(lái)進(jìn)行文件校驗(yàn), 被大量應(yīng)用在軟件下載站,論壇數(shù)據(jù)庫(kù),系統(tǒng)文件安全等方面.
*2. 數(shù)字簽名;
*3. 安全訪問(wèn)認(rèn)證;
}
3> MD5加鹽
{
MD5 本身是不可逆運(yùn)算,但是,目前網(wǎng)絡(luò)上有很多數(shù)據(jù)庫(kù)支持反查詢.
MD5加鹽 就是在密碼哈希過(guò)程中添加的額外的隨機(jī)值.
注意:加鹽要足夠長(zhǎng),足夠復(fù)雜.
}
4> HMAC
{
HMAC 利用哈希算法,以一個(gè)密鑰和一個(gè)消息為輸入,生成一個(gè)消息摘要作為輸出.
HMAC 主要使用在身份認(rèn)證中;
認(rèn)證流程:
*1. 客戶端向服務(wù)器發(fā)送一個(gè)請(qǐng)求.
*2. 服務(wù)器接收到請(qǐng)求后,生成一個(gè)'隨機(jī)數(shù)'并通過(guò)網(wǎng)絡(luò)傳輸給客戶端.
*3. 客戶端將接收到的'隨機(jī)數(shù)'和'密鑰'進(jìn)行 HMAC-MD5 運(yùn)算,將得到的結(jié)構(gòu)作為認(rèn)證數(shù)據(jù)傳遞給服務(wù)器.
(實(shí)際是將隨機(jī)數(shù)提供給 ePass,密鑰也是存儲(chǔ)在 ePass中的)
*4. 與此同時(shí),服務(wù)器也使用該'隨機(jī)數(shù)'與存儲(chǔ)在服務(wù)器數(shù)據(jù)庫(kù)中的該客戶'密鑰'進(jìn)行 HMAC-MD5 運(yùn)算,如果
服務(wù)器的運(yùn)算結(jié)果與客戶端傳回的認(rèn)證數(shù)據(jù)相同,則認(rèn)為客戶端是一個(gè)合法用法.
}
5> 時(shí)間戳密碼(用戶密碼動(dòng)態(tài)變化)
{
相同的密碼明文 + 相同的加密算法 ===》 每次計(jì)算都得出不同的結(jié)果.可以充分保證密碼的安全性.
原理:將當(dāng)前時(shí)間加入到密碼中;
因?yàn)槊看蔚顷憰r(shí)間都不同,所以每次計(jì)算出的結(jié)果也都不相同.
服務(wù)器也需要采用相同的算法.這就需要服務(wù)器和客戶端時(shí)間一致.
注意:服務(wù)器端時(shí)間和客戶端時(shí)間,可以有一分鐘的誤差(比如:第59S發(fā)送的網(wǎng)絡(luò)請(qǐng)求,一秒鐘后服務(wù)器收到并作出響應(yīng),這時(shí)服務(wù)器當(dāng)前時(shí)間比客戶端發(fā)送時(shí)間晚一分鐘).
這就意味著,服務(wù)器需要計(jì)算兩次(當(dāng)前時(shí)間和一分鐘之前兩個(gè)時(shí)間點(diǎn)各計(jì)算一次).只要有一個(gè)結(jié)果是正確的,就可以驗(yàn)證成功!
}
// IP輔助/手機(jī)綁定...
}
/------------------------------03 鑰匙串訪問(wèn) -------------------------------------/
重點(diǎn): 1.鑰匙串訪問(wèn)
{
蘋果在 iOS 7.0.3 版本以后公布鑰匙串訪問(wèn)的SDK. 鑰匙串訪問(wèn)接口是純C語(yǔ)言的.
鑰匙串使用 AES 256加密算法,能夠保證用戶密碼的安全.
鑰匙串訪問(wèn)的第三方框架(SSKeychain),是對(duì) C語(yǔ)言框架 的封裝.注意:不需要看源碼.
鑰匙串訪問(wèn)的密碼保存在哪里?只有蘋果才知道.這樣進(jìn)一步保障了用戶的密碼安全.
使用步驟:
{
// 獲取應(yīng)用程序唯一標(biāo)識(shí).
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
// 1.利用第三方框架,將用戶密碼保存在鑰匙串
[SSKeychain setPassword:self.pwdText.text forService:bundleId account:self.usernameText.text];
"注意"三個(gè)參數(shù):
1.密碼:可以直接使用明文.鑰匙串訪問(wèn)本身是使用 AES 256加密,就是安全的.所以使用的時(shí)候,直接傳遞密碼明文就可以了.
2.服務(wù)名:可以隨便亂寫,建議唯一! 建議使用 bundleId.
bundleId是應(yīng)用程序的唯一標(biāo)識(shí),每一個(gè)上架的應(yīng)用程序都有一個(gè)唯一的 bundleId
3.賬戶名:直接用用戶名稱就可以.
// 2.從鑰匙串加載密碼
self.pwdText.text = [SSKeychain passwordForService:bundleId account:self.usernameText.text];
}
}
/--------------------------- 04 指紋識(shí)別 ---------------------------------------/
重點(diǎn): 1.指紋識(shí)別用法
{
指紋識(shí)別功能是 iphone 5S之后推出的.SDK是 iOS 8.0 推出!
推出指紋識(shí)別功能的目的,是為了簡(jiǎn)化移動(dòng)支付環(huán)節(jié),占領(lǐng)移動(dòng)支付市場(chǎng).
使用步驟:
{
1> 導(dǎo)入框架;
#import <LocalAuthentication/LocalAuthentication.h>
2> 指紋識(shí)別的實(shí)現(xiàn):
{
1. 需要判斷手機(jī)系統(tǒng)版本是否是 iOS 8.0 以上的版本.只有 iOS 8.0 以上才支持.
// 獲得當(dāng)前系統(tǒng)版本號(hào)
float version = [UIDevice currentDevice].systemVersion.floatValue;
if (version < 8.0 ) // 判斷當(dāng)前系統(tǒng)版本
{
NSLog(@"系統(tǒng)版本太低,請(qǐng)升級(jí)至最新系統(tǒng)");
return;
}
2. 實(shí)例化指紋識(shí)別對(duì)象,判斷當(dāng)前設(shè)備是否支持指紋識(shí)別功能(是否帶有TouchID).
// 1> 實(shí)例化指紋識(shí)別對(duì)象
LAContext *laCtx = [[LAContext alloc] init];
// 2> 判斷當(dāng)前設(shè)備是否支持指紋識(shí)別功能.
if (![laCtx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:NULL])
{ // 如果設(shè)備不支持指紋識(shí)別功能
NSLog(@"該設(shè)備不支持指紋識(shí)別功能");
return;
};
3.指紋登陸(默認(rèn)是異步方法)
// 指紋登陸
[laCtx evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"指紋登陸" reply:^(BOOL success, NSError *error)
{
// 如果成功,表示指紋輸入正確.
if (success) {
NSLog(@"指紋識(shí)別成功!");
}else
{
NSLog(@"指紋識(shí)別錯(cuò)誤,請(qǐng)?jiān)俅螄L試");
}
}];
}
}
}