Hash,通常翻譯作「散列」,也有直接音譯爲「哈希」的,就是把任意長度的輸入經過散列算法變換成固定長度的輸出,該輸出就是散列值。 簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數算法
既然hash的運算結果是定長的,那麼必然會出現多個數據的hash相同的狀況,這被叫作散列碰撞安全
md5 001.png"
輸出的hash值爲MD5 (001.png) = 794f38b127db2e24e23a59d1fcb7a700
複製代碼
修更名字+後綴名爲「md5 002.mp3」,終端命令md5 002.mp3"
輸出的hash值爲bash
MD5 (002.mp3) = 794f38b127db2e24e23a59d1fcb7a700
複製代碼
修改回「001.png」,Ctrl+C Ctrl+V複製一份圖片,命名爲「002.png」,終端命令md5 002.png"
服務器
MD5 (002.png) = 794f38b127db2e24e23a59d1fcb7a700
複製代碼
將圖片打包成「001.zip」,終端命令md5 001.png.zip
網絡
MD5 (001.png.zip) = eca9687c64a1a62154582186214a97be
複製代碼
上述操做得出幾個結論: ① 修改文件名或後綴名不會改變其二進制(hash值),後綴名實際上是給操做系統看的——讓操做系統判斷用什麼軟件打開它 ② 複製粘貼的本質是對二進制的複製粘貼 ③ 只有壓縮操做纔會改變二進制app
因爲hash運算的不可逆,讓它在不少領域都大放異彩函數
若是直接用明文傳輸密碼,黑客能直接抓取到網絡請求,用戶密碼會「一絲不掛」的出如今黑客面前;又若是使用RSA加密傳輸,客戶端加密服務器解密,豈不是美滋滋?可是用戶密碼仍是會明文保存在服務器端,這樣是很不安全的!!! 互聯網有兩個原則:① 網絡傳輸不容許明文傳遞用戶隱私信息;② 本地不容許明文保存用戶隱私信息網站
那麼直接使用MD5加密用戶密碼呢?或許不少小型外包就是這麼處理的,但這種方案也是很不全的,由於hash算法是不可逆的。只要窮舉千千萬萬種hash算法的結果,而後再進行反向查詢,用戶的密碼也會垂手可得會拿到,好比www.cmd5.com/這個網站 搜索引擎
那咱們再嘗試嘗試屢次MD5呢?其實也是同樣的,CMD5這個網站能夠選擇類型進行反向查詢,屢次嵌套並無論用加鹽是什麼意思呢?就是在用戶的明文密碼後面加一點「做料」——一串奇奇怪怪的字符串,而後再作hash運算,好比「123456da.gjio1ra」再作MD5運算髮送給服務器。 這種方案的用戶密碼不能簡單快速的破譯出明文密碼,可是也能經過暴力破解。與之同時帶來一系列的危害:破解出明文密碼,也就知道了鹽,由於鹽是寫死的,那麼全部用戶的密碼也均可以垂手可得的破解出來,因此在這種方案中對「鹽」的保護尤其重要。其次,各個客戶端、服務器都知道「鹽」的具體內容,那公司能保證全部開發工程師離職了不透露出去嗎?咱們作開發的應該作到盡善盡美,不能讓這些人爲因素影響咱們的app安全! 既然寫死「鹽」不行,那麼咱們能夠用動態鹽來解決問題加密
HMAC是使用一個密鑰加密,而且作兩次散列運算,獲得一個hash值。它是一種方案,不是加密算法。在實際開發中HMAC的密鑰來自於服務器,是隨機的,每一個帳號各不相同 接下來經過多種登陸狀況理一下登陸邏輯:
① 註冊
a. 用戶在客戶端填寫好帳號、密碼等信息後點擊註冊,開始註冊請求,並將帳號Feng
發送給服務器
b. 服務器對帳號Feng
進行校驗,若是可用的話,隨機生成一個密鑰key
發送給客戶端
c. 客戶端對進行HMAC,再將帳號+密碼發送給服務器,服務器將帳號Feng
+密鑰key
+密碼hmac
一一對應保存。而後返回註冊成功的請求結果,客戶端就能將密鑰key
存儲起來了
這樣子一個帳號對應一個密鑰,大大提升了登陸安全性。可是想一下萬一用戶換了臺設備登陸,那不是拿不到key了?因此咱們還得豐富一下咱們的登陸邏輯
② 換設備登陸
a. 用戶在客戶端填寫好帳號、密碼等信息後點擊登陸,客戶端如今本地查找帳號對應的密鑰,若是本地有對應的key直接走c,若是沒有的話將帳號Feng
發送給服務器並請求
密鑰key
b. 服務器對帳號Feng
進行查找,將帳號對應的密鑰key
返回給客戶端
c. 客戶端對明文密碼hmac獲得密碼hmac
,將帳號Feng
+密鑰key
+密碼hmac
發送給服務器。若是服務器帳號密碼匹配成功,客戶端將密鑰key
保存;反之不能保存
③ 設備鎖業務
a. 設備B初次登陸,並向服務器索要keyb. 服務器詢問原設備A是否開始設備鎖,若是沒開就自定發送key給B;若是開了就向設備A訪問權限,A贊成了才能發送
c. 服務器對帳號Feng
進行查找,將帳號對應的密鑰key
返回給客戶端
d. 同②-c
HMAC的加密方案已經至關安全了,可是客戶端發送給服務器的密碼照樣能被截取到,第三方只要帳號、密碼一匹配就能簡簡單單登陸,因此咱們要對網絡請求數據進行一些處理,咱們採用的方法是加時間戳:
a. 發起登陸請求
b. 服務器返回時間戳給客戶端
c. 照着(HMAC哈希值+時間戳).MD5
進行運算,這裏的時間戳不是本地的系統時間,而是發起登陸請求時服務器返回給客戶端的時間戳(只取到分鐘)而後將HMAC密碼拼接上時間戳,再次進行MD5發送給服務器
d. 服務器也用一樣的算法進行運算,先匹配同一分鐘的哈希值,匹配不成功再匹配上一分鐘的哈希值
這樣作可以讓用戶的密碼隨着時間變化而變化,黑客只能在最多兩分鐘內使用截獲到的密碼(最少1分01秒,最多1分59秒)
數字簽名,就是隻有信息的發送者才能產生的別人沒法僞造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證實。
圖文並茂才能更好地闡述觀點——xx去銀行取十塊錢的過程
a. 用戶要取10元b. 銀行給了你10元
c. 用戶拿到10元
a. 用戶要取10元b. 黑客修改:「用戶要取20元」
c. 銀行轉出20元
d. 黑客拿到10元,用戶拿到10元
a. 用戶要取10元 b. 黑客想修改爲:「用戶要取20元」,但修改不了 c. 銀行轉出20元 d. 用戶拿到10元 ######3. 原理 a. 原始數據HASH加密b. 使用RSA對HASH值進行加密(數字簽名)
c. 將原始數據+數字簽名,一塊兒發給服務器驗證 黑客沒有私鑰,不能對其進行解密; 傳輸過程當中,沒有密鑰傳遞; hash值判斷原始值有無修改
注:加密數字信息叫數字簽名,加密代碼叫代碼簽名,加密引用叫應用簽名
非對稱加密被叫作現代加密算法,對稱加密算法則叫作傳統加密算法
對稱加密算法
來講,密鑰的保護本就尤其重要,3DES使用三個密鑰對密鑰保管更加不易message.text
123456123456123456
123456123456123456
123456123456123456
123456123456123456
複製代碼
openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out msg1.bin
用DES加密,選擇ECB應用模式,密鑰爲616263,不加鹽message.text
,最後一組123456->223456123456123456123456
123456123456123456
123456123456123456
123456123456223456
複製代碼
xxd msg1.bin
和xxd msg2.bin
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應用模式,初始化向量爲0102030405060708,密鑰爲616263,不加鹽xxd msg3.bin
和xxd msg4.bin