一、hash
1. 什么是hash骡澈?
Hash锅纺,一般翻譯做“散列”,也有直接音譯為“哈侠吲梗”的囤锉,就是把任意長(zhǎng)度的輸入通過(guò)散列算法變換成固定長(zhǎng)度的輸出,該輸出就是散列值护锤。
簡(jiǎn)單的說(shuō)就是一種將任意長(zhǎng)度的消息壓縮到某一固定長(zhǎng)度的消息摘要的函數(shù)
2. hash的特點(diǎn)
- 算法是公開的
- 對(duì)相同數(shù)據(jù)的運(yùn)算結(jié)果是一樣的
- 對(duì)不同數(shù)據(jù)的運(yùn)算結(jié)果是定長(zhǎng)的嚼锄,默認(rèn)是128位,32個(gè)字符
- 無(wú)法進(jìn)行逆運(yùn)算(取決于hash的底層原理——單方向映射)
- 信息指紋蔽豺,常用來(lái)作數(shù)據(jù)識(shí)別
既然hash的運(yùn)算結(jié)果是定長(zhǎng)的区丑,那么必然會(huì)出現(xiàn)多個(gè)數(shù)據(jù)的hash相同的情況,這被叫做散列碰撞
3. hash的用途
- 用戶密碼的加密
hash算法是一個(gè)單向函數(shù)。它可以將任何大小的數(shù)據(jù)轉(zhuǎn)化為定長(zhǎng)的“指紋”沧侥,并且無(wú)法被反向計(jì)算可霎。另外,即使數(shù)據(jù)源只改動(dòng)了一丁點(diǎn)宴杀,哈希的結(jié)果也會(huì)完全不同 - 數(shù)字簽名
將在本文第三章講到 - 搜索引擎
“中國(guó)”癣朗、“浙江”、“廣廈”這三個(gè)詞無(wú)論排列順序怎么變化旺罢,搜索的結(jié)果都是一樣的旷余,因?yàn)檫@是將這三個(gè)詞的128位hash值進(jìn)行相加,結(jié)果都是一樣的 - 版權(quán)
如百度云的秒傳功能扁达,你在百度云上傳一份文件正卧,百度云會(huì)先判斷網(wǎng)盤上是否有和它一樣的hash值,如果有的話跪解,再判斷文件類型炉旷、二進(jìn)制前后兩百位是否一樣..(具體咱也不清楚)等等。如果都滿足的話認(rèn)為是同一份數(shù)據(jù)實(shí)現(xiàn)秒傳
又如接下來(lái)的操作:
一張圖片名為“001.png”的圖片用終端命令md5 001.png"
輸出的hash值為
MD5 (001.png) = 794f38b127db2e24e23a59d1fcb7a700
修改名字+后綴名為“md5 002.mp3”叉讥,終端命令md5 002.mp3"
輸出的hash值為
MD5 (002.mp3) = 794f38b127db2e24e23a59d1fcb7a700
修改回“001.png”窘行,Ctrl+C Ctrl+V復(fù)制一份圖片,命名為“002.png”图仓,終端命令md5 002.png"
MD5 (002.png) = 794f38b127db2e24e23a59d1fcb7a700
將圖片打包成“001.zip”罐盔,終端命令md5 001.png.zip
MD5 (001.png.zip) = eca9687c64a1a62154582186214a97be
上述操作得出幾個(gè)結(jié)論:
① 修改文件名或后綴名不會(huì)改變其二進(jìn)制(hash值),后綴名其實(shí)是給操作系統(tǒng)看的——讓操作系統(tǒng)判斷用什么軟件打開它
② 復(fù)制粘貼的本質(zhì)是對(duì)二進(jìn)制的復(fù)制粘貼
③ 只有壓縮操作才會(huì)改變二進(jìn)制
由于hash運(yùn)算的不可逆救崔,讓它在很多領(lǐng)域都大放異彩
二惶看、 hash在加密用戶密碼中的方案
1. 明文請(qǐng)求
如果直接用明文傳輸密碼,黑客能直接抓取到網(wǎng)絡(luò)請(qǐng)求帚豪,用戶密碼會(huì)“一絲不掛”的出現(xiàn)在黑客面前碳竟;又如果使用RSA加密傳輸草丧,客戶端加密服務(wù)器解密狸臣,豈不是美滋滋?但是用戶密碼還是會(huì)明文保存在服務(wù)器端昌执,這樣是很不安全的V蛞唷!懂拾!
互聯(lián)網(wǎng)有兩個(gè)原則:① 網(wǎng)絡(luò)傳輸不允許明文傳遞用戶隱私信息煤禽;② 本地不允許明文保存用戶隱私信息
2. 直接MD5加密/多次MD5加密
那么直接使用MD5加密用戶密碼呢?或許很多小型外包就是這么處理的岖赋,但這種方案也是很不全的檬果,因?yàn)閔ash算法是不可逆的。只要窮舉千千萬(wàn)萬(wàn)種hash算法的結(jié)果,然后再進(jìn)行反向查詢选脊,用戶的密碼也會(huì)輕而易舉會(huì)拿到杭抠,比如https://www.cmd5.com/這個(gè)網(wǎng)站
3. 加固定鹽
加鹽是什么意思呢?就是在用戶的明文密碼后面加一點(diǎn)“作料”——一串奇奇怪怪的字符串钝的,然后再做hash運(yùn)算翁垂,比如“123456da.gjio1ra”再做MD5運(yùn)算發(fā)送給服務(wù)器。
這種方案的用戶密碼不能簡(jiǎn)單快速的破譯出明文密碼硝桩,但是也能通過(guò)暴力破解沿猜。與之同時(shí)帶來(lái)一系列的危害:破解出明文密碼,也就知道了鹽亿柑,因?yàn)辂}是寫死的邢疙,那么所有用戶的密碼也都可以輕而易舉的破解出來(lái),所以在這種方案中對(duì)“鹽”的保護(hù)尤為重要望薄。其次疟游,各個(gè)客戶端、服務(wù)器都知道“鹽”的具體內(nèi)容痕支,那公司能保證所有開發(fā)工程師離職了不透露出去嗎颁虐?我們做開發(fā)的應(yīng)該做到盡善盡美,不能讓這些人為因素影響我們的app安全卧须!
既然寫死“鹽”不行另绩,那么我們可以用動(dòng)態(tài)鹽來(lái)解決問題
4. HMAC
HMAC是使用一個(gè)密鑰加密,并且做兩次散列運(yùn)算花嘶,得到一個(gè)hash值笋籽。它是一種方案,不是加密算法椭员。在實(shí)際開發(fā)中HMAC的密鑰來(lái)自于服務(wù)器车海,是隨機(jī)的,每個(gè)賬號(hào)各不相同
接下來(lái)通過(guò)多種登錄情況理一下登錄邏輯:
① 注冊(cè)
a. 用戶在客戶端填寫好賬號(hào)隘击、密碼等信息后點(diǎn)擊注冊(cè)侍芝,開始注冊(cè)請(qǐng)求,并將
賬號(hào)Feng
發(fā)送給服務(wù)器b. 服務(wù)器對(duì)
賬號(hào)Feng
進(jìn)行校驗(yàn)埋同,如果可用的話州叠,隨機(jī)生成一個(gè)密鑰key
發(fā)送給客戶端c. 客戶端對(duì)進(jìn)行HMAC,再將賬號(hào)+密碼發(fā)送給服務(wù)器凶赁,服務(wù)器將
賬號(hào)Feng
+密鑰key
+密碼hmac
一一對(duì)應(yīng)保存咧栗。然后返回注冊(cè)成功的請(qǐng)求結(jié)果逆甜,客戶端就能將密鑰key
存儲(chǔ)起來(lái)了
這樣子一個(gè)賬號(hào)對(duì)應(yīng)一個(gè)密鑰,大大提高了登錄安全性致板。但是想一下萬(wàn)一用戶換了臺(tái)設(shè)備登錄忆绰,那不是拿不到key了?所以我們還得豐富一下我們的登錄邏輯
② 換設(shè)備登錄
a. 用戶在客戶端填寫好賬號(hào)可岂、密碼等信息后點(diǎn)擊登錄错敢,客戶端現(xiàn)在本地查找賬號(hào)對(duì)應(yīng)的密鑰,如果本地有對(duì)應(yīng)的key直接走c缕粹,如果沒有的話將
賬號(hào)Feng
發(fā)送給服務(wù)器并請(qǐng)求密鑰key
b. 服務(wù)器對(duì)
賬號(hào)Feng
進(jìn)行查找稚茅,將賬號(hào)對(duì)應(yīng)的密鑰key
返回給客戶端c. 客戶端對(duì)明文密碼hmac得到
密碼hmac
,將賬號(hào)Feng
+密鑰key
+密碼hmac
發(fā)送給服務(wù)器平斩。如果服務(wù)器賬號(hào)密碼匹配成功亚享,客戶端將密鑰key
保存;反之不能保存
③ 設(shè)備鎖業(yè)務(wù)
a. 設(shè)備B初次登錄绘面,并向服務(wù)器索要key
b. 服務(wù)器詢問原設(shè)備A是否開始設(shè)備鎖欺税,如果沒開就自定發(fā)送key給B;如果開了就向設(shè)備A訪問權(quán)限揭璃,A同意了才能發(fā)送
b. 服務(wù)器對(duì)
賬號(hào)Feng
進(jìn)行查找晚凿,將賬號(hào)對(duì)應(yīng)的密鑰key
返回給客戶端c. 同②-c
- 防止被抓去網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)——加時(shí)間戳
HMAC的加密方案已經(jīng)相當(dāng)安全了,但是客戶端發(fā)送給服務(wù)器的密碼照樣能被截取到瘦馍,第三方只要賬號(hào)歼秽、密碼一匹配就能簡(jiǎn)簡(jiǎn)單單登錄,所以我們要對(duì)網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)進(jìn)行一些處理情组,我們采用的方法是加時(shí)間戳:
a. 發(fā)起登錄請(qǐng)求
b. 服務(wù)器返回時(shí)間戳給客戶端
c. 照著(HMAC哈希值+時(shí)間戳).MD5
進(jìn)行運(yùn)算燥筷,這里的時(shí)間戳不是本地的系統(tǒng)時(shí)間,而是發(fā)起登錄請(qǐng)求時(shí)服務(wù)器返回給客戶端的時(shí)間戳(只取到分鐘)然后將HMAC密碼拼接上時(shí)間戳院崇,再次進(jìn)行MD5發(fā)送給服務(wù)器
d. 服務(wù)器也用同樣的算法進(jìn)行運(yùn)算肆氓,先匹配同一分鐘的哈希值,匹配不成功再匹配上一分鐘的哈希值
這樣做能夠讓用戶的密碼隨著時(shí)間變化而變化底瓣,黑客只能在最多兩分鐘內(nèi)使用截獲到的密碼(最少1分01秒谢揪,最多1分59秒)
總結(jié):建議用戶密碼采用先HMAC再時(shí)間戳的方案
也有賬號(hào)動(dòng)態(tài)鹽,密碼時(shí)間戳的方案
三濒持、數(shù)字簽名
1. 含義
數(shù)字簽名键耕,就是只有信息的發(fā)送者才能產(chǎn)生的別人無(wú)法偽造的一段數(shù)字串寺滚,這段數(shù)字串同時(shí)也是對(duì)信息的發(fā)送者發(fā)送信息真實(shí)性的一個(gè)有效證明柑营。
2. 作用
圖文并茂才能更好地闡述觀點(diǎn)——xx去銀行取十塊錢的過(guò)程
a. 用戶要取10元
b. 銀行給了你10元
c. 用戶拿到10元
a. 用戶要取10元
b. 黑客修改:“用戶要取20元”
c. 銀行轉(zhuǎn)出20元
d. 黑客拿到10元,用戶拿到10元
a. 用戶要取10元
b. 黑客想修改成:“用戶要取20元”村视,但修改不了
c. 銀行轉(zhuǎn)出20元
d. 用戶拿到10元
3. 原理
a. 原始數(shù)據(jù)HASH加密
b. 使用RSA對(duì)HASH值進(jìn)行加密(數(shù)字簽名)
c. 將原始數(shù)據(jù)+數(shù)字簽名官套,一起發(fā)給服務(wù)器驗(yàn)證
黑客沒有私鑰,不能對(duì)其進(jìn)行解密;
傳輸過(guò)程中奶赔,沒有密鑰傳遞惋嚎;
hash值判斷原始值有無(wú)修改
注:加密數(shù)字信息叫數(shù)字簽名,加密代碼叫代碼簽名站刑,加密引用叫應(yīng)用簽名
四另伍、對(duì)稱加密
1. 含義:明文通過(guò)密鑰加密得到密文。密文通過(guò)密鑰解密得到明文
非對(duì)稱加密被叫做現(xiàn)代加密算法绞旅,對(duì)稱加密算法則叫做傳統(tǒng)加密算法
2. 對(duì)稱加密算法有三種:
- DES:數(shù)據(jù)加密標(biāo)準(zhǔn)摆尝,因?yàn)閺?qiáng)度低,所以用得少
- 3DES:使用三個(gè)密鑰因悲,對(duì)原始數(shù)據(jù)進(jìn)行三次加密
對(duì)于對(duì)稱加密算法
來(lái)說(shuō)堕汞,密鑰的保護(hù)本就尤為重要,3DES使用三個(gè)密鑰對(duì)密鑰保管更加不易 - AES:高級(jí)加密標(biāo)準(zhǔn)
由于AES加密強(qiáng)度高晃琳,常用RSA加密AES的密鑰
3. 常見的應(yīng)用模式有兩種:
- ECB:電子密碼本模式讯检。每一塊數(shù)據(jù),獨(dú)立加密
最基本的加密模式卫旱,也就是通常理解的加密人灼,相同的明文將永遠(yuǎn)加密成相同的密文,無(wú)初始向量顾翼,容易受到密碼本重放攻擊挡毅,一般情況下很少用 - CBC:密碼分組鏈接模式。使用一個(gè)密鑰和一個(gè)初始化向量對(duì)數(shù)據(jù)執(zhí)行加密
明文被加密前要與前面的密文進(jìn)行異或運(yùn)算后再加密暴构,因此只要選擇不同的初始向量跪呈,相同的密文加密后會(huì)形成不同的密文,這是目前應(yīng)用最廣泛的模式取逾。CBC加密后的密文是上下文相關(guān)的耗绿,但明文的錯(cuò)誤不會(huì)傳遞到后續(xù)分組,但如果一個(gè)分組丟失砾隅,后面的分組將全部作廢(同步錯(cuò)誤)误阻。
CBC可以有效的保證密文的完整性,如果一個(gè)數(shù)據(jù)塊在傳遞是丟失或改變晴埂,后面的數(shù)據(jù)將無(wú)法正常解密究反。
為了更生動(dòng)形象的對(duì)比ECB和CBC,我們將用終端演示來(lái)比較
- 生成一個(gè)
message.text
123456123456123456
123456123456123456
123456123456123456
123456123456123456
- 終端命令
openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out msg1.bin
用DES加密儒洛,選擇ECB應(yīng)用模式精耐,密鑰為616263,不加鹽 - 修改
message.text
琅锻,最后一組123456->223456
123456123456123456
123456123456123456
123456123456123456
123456123456223456
- 終端命令
xxd msg1.bin
和xxd msg2.bin
ECB加密結(jié)果對(duì)比 - 同樣的操作卦停,選擇CBC
openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out msg3.bin
openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out msg4.bin
用DES加密向胡,選擇CBC應(yīng)用模式,初始化向量為0102030405060708惊完,密鑰為616263僵芹,不加鹽 - 終端命令
xxd msg3.bin
和xxd msg4.bin
CBC加密結(jié)果對(duì)比