目錄
前言?
什么是MD5??
?加鹽算法
那別的人會不會跟你得到相同的UUID??
如何使用鹽加密?
代碼實現(xiàn)
前言?
????????對于我們常見的登錄的時候需要用到的組件,加密是一個必不可少的東西,如果我們往數(shù)據(jù)庫存放用戶的密碼,是直接以明文存儲的話,那么數(shù)據(jù)被竊取的時候,損失也就是最大的,因為別人可以很直觀的看到你的用戶數(shù)據(jù),不需要任何破解成本。
? ? ? ? 所以我們需要對其加密。
? ? ? ? 目前最常見的兩種數(shù)據(jù)加密方法:
- MD5加密
- 加鹽算法
什么是MD5??
? ? ? ? 簡單來說,md5就是講遺傳字符串通過某種特定的算法,來將其變化成另外一種形式,這樣子就從明文的外觀變成另外一個樣子。但是由于背后的算法格式是固定的,所以每一個字符串都有固定的MD5格式。
? ? ? ?有的用戶為了方便記憶,把密碼設(shè)置成簡單的,有規(guī)律的字母或者數(shù)字組合,有的也喜歡使用單獨一個單詞這種,舉一個簡單的例子,例如密碼1234567,和密碼1726354,這兩種密碼,因為格式簡單,很容易就被一次一次的試出來,也就是被暴力破解。
? ? ? ? 然后我們使用1234567進行MD5加密,但是這樣就會讓數(shù)據(jù)完全處于安全狀態(tài)嗎?
? ? ? ? 具體如何破解?也就是講得到的,講得到的密碼進行MD5轉(zhuǎn)換成為對應(yīng)的哈希,然后于最初的哈希進行比對,要是匹配,那么這個密碼就已經(jīng)暴露給別人了
? ? ? ? MD5底層存在一張彩虹表,幾乎標記了所有字符串的MD5對照表。
????????有了彩虹表MD5就相當于是不存在了,因為一種字符串就只有一種特定的MD5格式
?加鹽算法
? ? ? ? 什么是鹽?
? ? ? ? 其實鹽就是一個隨機值,沒有任何規(guī)律,通過UUID.randomUUID()來生成一個唯一鹽值。這個uuid是唯一的,具體唯一就是根據(jù)你的mac地址等內(nèi)容生成的一個世界唯一的值,
那別的人會不會跟你得到相同的UUID??
下面的內(nèi)容來自百度百科:
? ? ? ? 官方說明:產(chǎn)生錯誤的情況非常低,是故大可不必考慮這個重復(fù)的問題
如何使用鹽加密?
? ? ? ? ?這里存在一個合約公式,也就是:鹽值(32位)+? $? + MD5加密后的密碼
? ? ? ? 加密思路:用戶輸入一個明文密碼,通過UUID得到一個鹽值,這段密碼首先使用MD5和鹽值進行一個基本的加密,然后使用合約公式,將鹽值和使用MD5+鹽值生成的合約公式存入數(shù)據(jù)庫
? ? ? ? 如何解密:這里的解密,不是指的直接將我們得到的合約公式又解密成明文,比如,用戶想要登錄,于是他輸入了他之前設(shè)置的密碼。這個密碼被后端得到之后,就會進行驗證,具體就是首先記住這個明文,然后通過數(shù)據(jù)庫中存儲的對應(yīng)用戶的合約公式拿出來,通過$來獲取鹽值,然后將用戶輸入的明文和拿到的鹽值進行MD5加密,然后再合成一個:
鹽值(32位)+? $? + MD5加密(鹽值+用戶輸入的密碼),
那么現(xiàn)在就有兩個合約公式了,一個是用戶注冊時候生成的,一個是用戶剛剛輸入的,后臺自動生成的合約公式
? ? ? ? 如果兩個合約公式是一樣的,那么就說明現(xiàn)在正在登錄這個賬戶的人是這個賬戶的持有者,就可以允許訪問
代碼實現(xiàn)
? ? ? ? ?在實現(xiàn)這個功能之前,你需要引入一個工具類,可以前往maven下載,地址為:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version> <!--根據(jù)需要選擇合適版本-->
</dependency>
代碼案例:
import org.apache.commons.codec.digest.DigestUtils;
public class Main {
public static void main(String[] args) {
String input = "Hello World"; // 輸入字符串
// 計算MD5值
String md5Hash = DigestUtils.md5Hex(input);
System.out.println("MD5 Hash: " + md5Hash);
}
}
根據(jù)上面的案例進行加密:
// import org.apache.commons.codec.digest.DigestUtils;
//
// import java.util.UUID;
public static String encrypt(String password) {
// 首先生產(chǎn)一個鹽值
// UUID.randomUUID() 會生成32位數(shù)字,然后+4位‘-’,我們不需要關(guān)注‘-’在鹽值的什么位置,我們只需要去除它
String salt = UUID.randomUUID().toString();
System.out.println(salt);
// 去除‘-’
salt = salt.replaceAll("-","");
// 然后使用鹽值和傳進來的密碼進行md5加密
String saltPassowrd = DigestUtils.md5Hex((salt+password).getBytes());
// 然后和鹽值進行拼接,然后返回
String finalPassword = salt + '$' + saltPassowrd;
return finalPassword;
}
}
解密:文章來源:http://www.zghlxwxcb.cn/news/detail-796093.html
? ? ? ? 解密的思路就是講用戶輸入的密碼重新進行一次加密,然后比對從數(shù)據(jù)庫中拿到的是不是一樣的:文章來源地址http://www.zghlxwxcb.cn/news/detail-796093.html
public static boolean check(String inputPassword, String finalPassword){
//首先判斷這兩個參數(shù)到底有沒有值,并且判斷數(shù)據(jù)庫中拿到的finalPassword的length是否為65;
if (inputPassword == null || inputPassword.isEmpty()) {
// 這里先判斷為不為空是因為后面的isEmpty的前提是字符串不為null,不然就會發(fā)生空指針異常
return false;
}
if (finalPassword == null || finalPassword.isEmpty() || finalPassword.length() != 65) {
return false;
}
// 從finalPassword中拿到鹽值
String salt = finalPassword.split("\\$")[0];
String saltPassword = DigestUtils.md5Hex((salt+inputPassword).getBytes());
String ret = salt + '$' + saltPassword;
if (ret.equals(finalPassword)) {
return true;
}
return false;
}
到了這里,關(guān)于手寫一個加鹽加密算法(java實現(xiàn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!