自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MD5 加密安全嗎?

安全 數(shù)據(jù)安全
只是簡(jiǎn)單的使用 MD5 加密是不安全的,因?yàn)槊總€(gè)字符串都會(huì)生成固定的密文,那么我們就可以使用彩虹表將密文還原出來(lái),所以它不是安全的。想要解決這個(gè)問(wèn)題,我們需要通過(guò)加鹽的手段,每次生成一個(gè)不同的密碼,就把這個(gè)問(wèn)題解決了。

MD5 是 Message Digest Algorithm 的縮寫(xiě),譯為信息摘要算法,它是 Java 語(yǔ)言中使用很廣泛的一種加密算法。MD5 可以將任意字符串,通過(guò)不可逆的字符串變換算法,生成一個(gè)唯一的 MD5 信息摘要,這個(gè)信息摘要也就是我們通常所說(shuō)的 MD5 字符串。那么問(wèn)題來(lái)了,MD5 加密安全嗎?

這道題看似簡(jiǎn)單,其實(shí)是一道送命題,很多人尤其是一些新入門(mén)的同學(xué)會(huì)覺(jué)得,安全啊,MD5 首先是加密的字符串,其次是不可逆的,所以它一定是安全的。如果你這樣回答,那么就徹底掉進(jìn)面試官給你挖好的坑了。

為什么呢?因?yàn)榇鸢甘恰安话踩?,而不是“安全”?/p>

1.彩虹表

MD5 之所以說(shuō)它是不安全的,是因?yàn)槊恳粋€(gè)原始密碼都會(huì)生成一個(gè)對(duì)應(yīng)的固定密碼,也就是說(shuō)一個(gè)字符串生成的 MD5 值是永遠(yuǎn)不變的。這樣的話(huà),雖然它是不可逆的,但可以被窮舉,而窮舉的“產(chǎn)品”就叫做彩虹表。

什么是彩虹表?

彩虹表是一個(gè)用于加密散列函數(shù)逆運(yùn)算的預(yù)先計(jì)算好的表, 為破解密碼的散列值(或稱(chēng)哈希值、微縮圖、摘要、指紋、哈希密文)而準(zhǔn)備。一般主流的彩虹表都在 100G 以上。這樣的表常常用于恢復(fù)由有限集字符組成的固定長(zhǎng)度的純文本密碼。這是空間/時(shí)間替換的典型實(shí)踐,比每一次嘗試都計(jì)算哈希的暴力破解處理時(shí)間少而儲(chǔ)存空間多,但卻比簡(jiǎn)單的對(duì)每條輸入散列翻查表的破解方式儲(chǔ)存空間少而處理時(shí)間多。

簡(jiǎn)單來(lái)說(shuō),彩虹表就是一個(gè)很大的,用于存放窮舉對(duì)應(yīng)值的數(shù)據(jù)表。以 MD5 為例,“1”的 MD5 值是“C4CA4238A0B923820DCC509A6F75849B”,而“2”的 MD5 值是“C81E728D9D4C2F636F067F89CC14862C”,那么就會(huì)有一個(gè) MD5 的彩虹表是這樣的:

原始值

加密值

1

C4CA4238A0B923820DCC509A6F75849B

2

C81E728D9D4C2F636F067F89CC14862C

...

...

大家想想,如果有了這張表之后,那么我就可以通過(guò) MD5 的密文直接查到原始密碼了,所以說(shuō)數(shù)據(jù)庫(kù)如果只使用 MD5 加密,這就好比用了一把插了鑰匙的鎖一樣不安全。

2.解決方案

想要解決以上問(wèn)題,我們需要引入“加鹽”機(jī)制。

鹽(Salt):在密碼學(xué)中,是指通過(guò)在密碼任意固定位置插入特定的字符串,讓散列后的結(jié)果和使用原始密碼的散列結(jié)果不相符,這種過(guò)程稱(chēng)之為“加鹽”。

說(shuō)的通俗一點(diǎn)“加鹽”就像炒菜一樣,放不同的鹽,炒出菜的味道就是不同的,咱們之前使用 MD5 不安全的原因是,每個(gè)原始密碼所對(duì)應(yīng)的 MD5 值都是固定的,那我們只需要讓密碼每次通過(guò)加鹽之后,生成的最終密碼都不同,這樣就能解決加密不安全的問(wèn)題了。

3.實(shí)現(xiàn)代碼

加鹽是一種手段、是一種解決密碼安全問(wèn)題的思路,而它的實(shí)現(xiàn)手段有很多種,我們可以使用框架如 Spring Security 提供的 BCrypt 進(jìn)行加鹽和驗(yàn)證,當(dāng)然,我們也可以自己實(shí)現(xiàn)加鹽的功能。

本文為了讓大家更好的理解加鹽的機(jī)制,所以我們自己來(lái)動(dòng)手來(lái)實(shí)現(xiàn)一下加鹽的功能。

實(shí)現(xiàn)加鹽機(jī)制的關(guān)鍵是在加密的過(guò)程中,生成一個(gè)隨機(jī)的鹽值,而且隨機(jī)鹽值盡量不要重復(fù),這時(shí),我們就可以使用 Java 語(yǔ)言提供的 UUID(Universally Unique Identifier,通用唯一識(shí)別碼)來(lái)作為鹽值,這樣每次都會(huì)生成一個(gè)不同的隨機(jī)鹽值,且永不重復(fù)。

加鹽的實(shí)現(xiàn)代碼如下:

import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.util.UUID;

public class PasswordUtil {
/**
* 加密(加鹽處理)
* @param password 待加密密碼(需要加密的密碼)
* @return 加密后的密碼
*/
public static String encrypt(String password) {
// 隨機(jī)鹽值 UUID
String salt = UUID.randomUUID().toString().replaceAll("-", "");
// 密碼=md5(隨機(jī)鹽值+密碼)
String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
return salt + "$" + finalPassword;
}
}

從上述代碼我們可以看出,加鹽的實(shí)現(xiàn)具體步驟是:

  • 使用 UUID 產(chǎn)生一個(gè)隨機(jī)鹽值;
  • 將隨機(jī)鹽值 + 原始密碼一起 MD5,產(chǎn)生一個(gè)新密碼(相同的原始密碼,每次都會(huì)生成一個(gè)不同的新密碼);
  • 將隨機(jī)鹽值 + "$"+上一步生成的新密碼加在一起,就是最終生成的密碼。
  • 那么,問(wèn)題來(lái)了,既然每次生成的密碼都不同,那么怎么驗(yàn)證密碼是否正確呢?

要驗(yàn)證密碼是否正確的關(guān)鍵是需要先獲取鹽值,然后再使用相同的加密方式和步驟,生成一個(gè)最終密碼和和數(shù)據(jù)庫(kù)中保存的加密密碼進(jìn)行對(duì)比,具體實(shí)現(xiàn)代碼如下:

import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.util.UUID;

public class PasswordUtil {
/**
* 加密(加鹽處理)
* @param password 待加密密碼(需要加密的密碼)
* @return 加密后的密碼
*/
public static String encrypt(String password) {
// 隨機(jī)鹽值 UUID
String salt = UUID.randomUUID().toString().replaceAll("-", "");
// 密碼=md5(隨機(jī)鹽值+密碼)
String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());
return salt + "$" + finalPassword;
}

/**
* 解密
* @param password 要驗(yàn)證的密碼(未加密)
* @param securePassword 數(shù)據(jù)庫(kù)中的加了鹽值的密碼
* @return 對(duì)比結(jié)果 true OR false
*/
public static boolean decrypt(String password, String securePassword) {
boolean result = false;
if (StringUtils.hasLength(password) && StringUtils.hasLength(securePassword)) {
if (securePassword.length() == 65 && securePassword.contains("$")) {
String[] securePasswordArr = securePassword.split("\\$");
// 鹽值
String slat = securePasswordArr[0];
String finalPassword = securePasswordArr[1];
// 使用同樣的加密算法和隨機(jī)鹽值生成最終加密的密碼
password = DigestUtils.md5DigestAsHex((slat + password).getBytes());
if (finalPassword.equals(password)) {
result = true;
}
}
}
return result;
}
}

總結(jié)

只是簡(jiǎn)單的使用 MD5 加密是不安全的,因?yàn)槊總€(gè)字符串都會(huì)生成固定的密文,那么我們就可以使用彩虹表將密文還原出來(lái),所以它不是安全的。想要解決這個(gè)問(wèn)題,我們需要通過(guò)加鹽的手段,每次生成一個(gè)不同的密碼,就把這個(gè)問(wèn)題解決了。

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2016-12-15 09:26:53

MD5加密

2015-03-23 11:21:08

2020-10-15 08:20:52

MD5算法加密的過(guò)程

2009-06-06 18:57:47

MD5加密類(lèi)Java Bean

2009-06-30 10:05:24

MD5加密JSP源碼

2020-02-25 16:30:36

MD5是不是加密

2021-02-19 11:55:36

C語(yǔ)言MD5加密

2011-12-28 13:14:39

2022-11-09 08:24:39

2009-09-09 18:35:07

C# 加密MD5和SHA1

2010-03-16 09:27:31

2009-10-26 14:06:03

2009-07-24 15:58:20

ASP.NET MD5ASP.NET SHA

2010-01-06 09:54:30

.NET Framew

2021-12-06 18:16:14

SQLCRCMD5

2017-06-28 14:38:44

2009-07-28 16:39:16

VB.NET的MD5加

2022-10-19 07:35:28

2021-06-07 10:00:41

MD5算法加密

2016-12-19 15:50:36

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)