一 . MD5
1.簡(jiǎn)單說(shuō)明
MD5:全稱是Message Digest Algorithm 5坐儿,譯為“消息摘要算法第5版”效果:對(duì)輸入信息生成唯一的128位散列值(32個(gè)字符)
2.MD5的特點(diǎn)
(1)對(duì)不同的數(shù)據(jù)加密,得到的結(jié)果是定長(zhǎng)的,MD5對(duì)不同的數(shù)據(jù)進(jìn)行加密,得到的結(jié)果都是32個(gè)字符.
(2)根據(jù)輸出值拴袭,不能得到原始的明文乳蓄,即其過(guò)程不可逆
(3)算法具有較好的安全性,而且免費(fèi)
(4)廣泛使用主要運(yùn)用在數(shù)字簽名微渠、文件完整性驗(yàn)證以及口令加密等方面
MD5用途
- 口令加密
- 搜索
將幾個(gè)關(guān)鍵字分別md5,在搜索這幾個(gè)關(guān)鍵字的時(shí)候,不管順序怎么樣,還是會(huì)得到大致相同的搜素結(jié)果鲁森。其實(shí)就是將這幾個(gè)關(guān)鍵字的md5值作一些特殊處理,比如相加振惰。
- 版權(quán)
不同的數(shù)據(jù) MD5 是不一樣的歌溉,比如一個(gè)視頻資源,放到服務(wù)器上的時(shí)候骑晶,會(huì)將md5值也放上去保存痛垛。如果是盜版的,md5值是不一樣的透罢。
3.MD5破解MD5解密網(wǎng)站:http://www.cmd5.com
4.如何使MD5加密更安全?
現(xiàn)在密碼學(xué)要求:同樣的算法榜晦,同樣的密碼明文,每次的結(jié)果不一樣(密碼有實(shí)效性)
第一種方式:加鹽(Salt)
在明文的固定位置插入隨機(jī)串羽圃,然后再進(jìn)行MD5
如果鹽是固定的乾胶,鹽有很多人知道(服務(wù)器,前端朽寞,客戶端)识窿,會(huì)被泄漏,不安全
static NSString *salt =@"fadsfdbvcxweioa43$^$^$$#@23123124";
NSString* password = [self.passField.text
stringByAppendingString:salt].md5String;
第二種方式:先加密脑融,后亂序
先對(duì)明文進(jìn)行MD5喻频,然后對(duì)加密得到的MD5串的字符進(jìn)行亂序
第三種方式:HMAC
現(xiàn)在使用的比較廣泛,安全級(jí)別更高,破解難度高肘迎。
但還是有風(fēng)險(xiǎn):每次結(jié)果一致甥温,有可能被暴力破解锻煌。
黑客模擬網(wǎng)絡(luò)請(qǐng)求,不需要真實(shí)密碼姻蚓,也可以獲取登陸權(quán)限宋梧。
給定一個(gè)密鑰(這個(gè)密鑰來(lái)自于服務(wù)器),對(duì)明文進(jìn)行密鑰拼接,并且做"兩次散列" -> 得到32位結(jié)果。
NSString* password = [self.passField.text
hmacMD5StringWithKey:@"hmackey"];
上面代碼 md5 的過(guò)程:使用密鑰hmackey對(duì)密碼加密狰挡,加密后做md5捂龄,得到32位字符串,再次使用 hmackey 加密加叁,再md5
HMAC使用方式 :(登陸注冊(cè)密碼加密)
- 注冊(cè)時(shí),向服務(wù)器索取密鑰(key)倦沧,服務(wù)器將密鑰和用戶的賬戶對(duì)應(yīng)起來(lái)保存在數(shù)據(jù)庫(kù)。
- 客戶端拿到key后保存在本地(鑰匙串保存它匕,登陸的時(shí)候需要用到這個(gè)key進(jìn)行加密)
- 切換了新的設(shè)備(換手機(jī)登錄或者登錄新的已有賬號(hào))
重新找服務(wù)器獲取key展融,服務(wù)器根據(jù)賬號(hào)給(比如qq,第一次登陸會(huì)比較慢,因?yàn)椴粌H要獲取key,還要獲取聊天信息)
eg: 用戶在A設(shè)備登陸成功后超凳,再去B設(shè)備登陸愈污,B從本地找key找不到,就會(huì)找服務(wù)器要(如果有密碼鎖就等待授權(quán)轮傍,如果沒(méi)有密碼鎖暂雹,就直接獲取)创夜,服務(wù)器會(huì)根據(jù)A設(shè)備(授權(quán))決定給不給(密碼鎖杭跪,也是根據(jù)這個(gè)key)
5、生成帶時(shí)間戳的密碼
使用時(shí)間戳驰吓,目前使用非常廣泛
思路:
- 客戶端注冊(cè)時(shí)輸入賬號(hào)和原始密碼涧尿,服務(wù)器會(huì)返回一個(gè)key給客戶端
- 服務(wù)器將賬號(hào),key,以及hmac后的密碼(EncryptPass)保存在數(shù)據(jù)庫(kù)
- 客戶端拿到key后檬贰,會(huì)將原始密碼結(jié)合key進(jìn)行一次hmac運(yùn)算姑廉,生成一個(gè)加密后的密碼(EncryptPass),加密后的密碼再結(jié)合當(dāng)前時(shí)間(這個(gè)時(shí)間要從服務(wù)器獲取)再做一次md5翁涤,生成新的加密密碼(finalPass)
- 客戶端結(jié)合時(shí)間生產(chǎn)密碼后桥言,會(huì)發(fā)送請(qǐng)求和服務(wù)器上的密碼作比較(服務(wù)器會(huì)用EncryptPass結(jié)合服務(wù)器當(dāng)前時(shí)間,或者當(dāng)前時(shí)間前一分鐘葵礼,生產(chǎn)服務(wù)器的finalPass,如果這兩個(gè)時(shí)間相同号阿,就登陸成功)
- 這樣根據(jù)時(shí)間來(lái)做,就算暴力破解或者模擬登陸鸳粉,已經(jīng)過(guò)了時(shí)效了扔涧,密碼早已經(jīng)變了。
(1) ------使用客戶端時(shí)間生成帶時(shí)間戳的密碼------
(NSString *)timePassword{
//1.設(shè)置密鑰key
NSString *key = @"itheima".md5String;
//2.使用密鑰key對(duì)密碼進(jìn)行HMac
NSString *pwd = [self.passField.texthmacMD5StringWithKey:key];
NSLog(@"key = %@",key);
//3.獲得當(dāng)前的系統(tǒng)時(shí)間
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
//指定時(shí)區(qū),真機(jī)通常需要指定時(shí)區(qū)
fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh"];
//設(shè)置時(shí)間格式
fmt.dateFormat = @"yyyy-MM-dd HH:mm";
//格式化當(dāng)前時(shí)間
NSString *dateStr = [fmt stringFromDate:[NSDate date]];
//4.用密碼+ 時(shí)間 生成密碼
pwd =[pwd stringByAppendingString:dateStr];
//5.返回hmac 結(jié)果
return [pwd hmacMD5StringWithKey:key];
}
NSString *password = [self timePassword];
(2) ------使用服務(wù)器時(shí)間,生成帶時(shí)間戳的密碼-----
(NSString *)timePassword{
//1.設(shè)置密鑰key
NSString *key = @"itheima".md5String;
//2.對(duì)密鑰key對(duì)密碼進(jìn)行HMac
NSString *pwd = [self.passField.text hmacMD5StringWithKey:key];
//3.獲得當(dāng)前服務(wù)器的系統(tǒng)時(shí)間
NSURL*url = [NSURL URLWithString:@"[http://localhost/hmackey.php](http://localhost/hmackey.php)"];
//使用同步獲取時(shí)間(注意:這里要使用同步,確定先獲得服務(wù)器的時(shí)間,后面的代碼才能執(zhí)行)
NSData *timeData = [NSData dataWithContentsOfURL:url];
//反序列化取出時(shí)間
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:timeData options:0 error:NULL];
NSString *dateStr = dict[@"key"];
//4.用密碼+ 時(shí)間 生成密碼
pwd =[pwd stringByAppendingString:dateStr];
//5.返回hmac 結(jié)果
return [pwd hmacMD5StringWithKey:key];
}
注意:要獲得服務(wù)器時(shí)間來(lái)對(duì)密碼進(jìn)行hmac枯夜。
有些人手機(jī)上的時(shí)間設(shè)置會(huì)比真實(shí)的時(shí)間的快5分鐘弯汰。如果是這樣的,就會(huì)導(dǎo)致客戶端獲得的系統(tǒng)時(shí)間和服務(wù)器獲得的系統(tǒng)時(shí)間相差幾分鐘卤档。那就會(huì)導(dǎo)致hmac 的結(jié)果不一致蝙泼,無(wú)法登錄。
網(wǎng)絡(luò)開(kāi)發(fā)中劝枣,不管是網(wǎng)絡(luò)傳輸還是在本地都不允許保存用戶的明文隱私數(shù)據(jù)
登陸注冊(cè)時(shí)密碼的處理方式:
用戶注冊(cè)的時(shí)候服務(wù)器對(duì)密碼進(jìn)行了加密處理,然后保存在數(shù)據(jù)庫(kù),服務(wù)器是不需要知道用戶的真實(shí)密碼的织鲸。
登陸的時(shí)候客戶端使用和服務(wù)器相同的加密方式舔腾,然后和服務(wù)器上加密后的密碼比較,來(lái)完成登陸搂擦。
如果android端和mac端有分歧稳诚,可以在mac終端用下面命令來(lái)檢驗(yàn)。
md5 -s "xxxxxxx"
保存密碼的方式:(如果想反算原始密碼)
1.NSUserDefaults
2.鑰匙串訪問(wèn)
- 蘋(píng)果的"生態(tài)圈",從 iOS7.0.3 版本開(kāi)放
- 在Mac上能夠動(dòng)態(tài)生成復(fù)雜密碼(AES 加密)
- 如果用戶訪問(wèn)網(wǎng)站,記住密碼,我們還可以看到記住的密碼明文
- 本身的所有接口都是 C 語(yǔ)言的.借助三方庫(kù)
二. 對(duì)稱加密
* 加密和解密使用同一個(gè)"密鑰"
* 密鑰的保密工作就非常的重要瀑踢,密鑰會(huì)定期更換
經(jīng)典算法
- DES 數(shù)據(jù)加密標(biāo)準(zhǔn)(用的比較少,因?yàn)閺?qiáng)度不夠).
- 3DES 使用3個(gè)密鑰,對(duì)相同的數(shù)據(jù)執(zhí)行三次加密,強(qiáng)度增強(qiáng).
- AES 高級(jí)加密標(biāo)準(zhǔn),目前美國(guó)國(guó)家安全局使用AES加密(鑰匙串訪問(wèn)就是使用AES加密)
對(duì)稱加密有兩種加密方式: ECB和CBC
ECB: 電子代碼本,就是將一個(gè)數(shù)據(jù)拆分為多塊,然后獨(dú)立加密
CBC: 密碼塊鏈,使用一個(gè)密鑰和一個(gè)初始化"向量"對(duì)數(shù)據(jù)執(zhí)行加密轉(zhuǎn)換扳还,能保證密文的完整性,如果一個(gè)數(shù)據(jù)發(fā)生改變,后面所有的數(shù)據(jù)將會(huì)被破壞
向量:某個(gè)方向的數(shù)量.
現(xiàn)代的密碼學(xué)都和幾何有關(guān)!因?yàn)閹缀?包含圓形\橢圓\球體)的變量是有規(guī)律的,但是結(jié)果是多變的
可以在終端通過(guò)命令來(lái)測(cè)試
//ECB加密
openssl enc -des-ecb -K 616263 -nosalt -in xxx.xxx -out XXX.XXX
//ECB解密
openssl enc -des-ecb -K 616263 -nosalt -in xxx.xxx -out XXX.XXX -d
//查看ECB加密之后的文件
$ xxd xxx.xxx
解釋:
-des-ecb : 使用ecb方式加密,
-K : 密鑰匙'abc'(注意:616263是16進(jìn)制的)
-nosalt : 不加鹽
-in xxx.xxx : 要加密的文件
-out XXX.XXX : 生成的加密文件
=============================================================================
//cbc方式加密
echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
解釋:
echo -n hello :要加密的字符串‘hello’
enc -aes-128-cbc : 使用cbc方式加密
-iv 0102030405060708 :向量是‘12345678’
-K : 密鑰匙'abc'(注意:616263是16進(jìn)制的)
-nosalt : 不加鹽
base64 :base64編碼
提示:
1> 加密過(guò)程是先加密橱夭,再base64編碼
2> 解密過(guò)程是先base64解碼氨距,再解密
三. 非對(duì)稱加密(RSA)
公鑰\私鑰(用公鑰加密,私鑰解密或者用私鑰加密,公鑰解密)