最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java面試題之MD5加密的安全性詳解

 更新時(shí)間:2022年10月19日 08:17:58   作者:磊哥  
MD5 是 Message Digest Algorithm 的縮寫(xiě),譯為信息摘要算法,它是 Java 語(yǔ)言中使用很廣泛的一種加密算法。本文將通過(guò)示例討論下MD5的安全性,感興趣的可以了解一下

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)?strong>答案是“不安全”,而不是“安全”。

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 的彩虹表是這樣的:

原始值加密值
1C4CA4238A0B923820DCC509A6F75849B
2C81E728D9D4C2F636F067F89CC14862C
......

大家想想,如果有了這張表之后,那么我就可以通過(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)題解決了。

到此這篇關(guān)于Java面試題之MD5加密的安全性詳解的文章就介紹到這了,更多相關(guān)Java MD5加密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java中Period類(lèi)的使用方法

    詳解Java中Period類(lèi)的使用方法

    Period類(lèi)通過(guò)年、月、日相結(jié)合來(lái)描述一個(gè)時(shí)間量,最高精度是天。本文將通過(guò)示例詳細(xì)為大家講講Period類(lèi)的使用,需要的可以參考一下
    2022-05-05
  • Java設(shè)計(jì)模式之適配器模式的示例詳解

    Java設(shè)計(jì)模式之適配器模式的示例詳解

    適配器模式,即將某個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)端期望的另一個(gè)接口的表示,主要目的是實(shí)現(xiàn)兼容性,讓原本因?yàn)榻涌诓黄ヅ?,沒(méi)辦法一起工作的兩個(gè)類(lèi),可以協(xié)同工作。本文將通過(guò)示例詳細(xì)介紹適配器模式,需要的可以參考一下
    2022-08-08
  • SpringCloud項(xiàng)目中Feign組件添加請(qǐng)求頭所遇到的坑及解決

    SpringCloud項(xiàng)目中Feign組件添加請(qǐng)求頭所遇到的坑及解決

    這篇文章主要介紹了SpringCloud項(xiàng)目中Feign組件添加請(qǐng)求頭所遇到的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 基于hibernate框架在eclipse下的配置方法(必看篇)

    基于hibernate框架在eclipse下的配置方法(必看篇)

    下面小編就為大家?guī)?lái)一篇基于hibernate框架在eclipse下的配置方法(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • SpringBoot常見(jiàn)錯(cuò)誤圖文總結(jié)

    SpringBoot常見(jiàn)錯(cuò)誤圖文總結(jié)

    最近在使用idea+Springboot開(kāi)發(fā)項(xiàng)目中遇到一些問(wèn)題,這篇文章主要給大家介紹了關(guān)于SpringBoot常見(jiàn)錯(cuò)誤總結(jié)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 分享Java死鎖的4種排查工具

    分享Java死鎖的4種排查工具

    這篇文章主要介紹了分享Java死鎖的4種排查工具,死鎖指的是兩個(gè)或兩個(gè)以上的運(yùn)算單元,都在等待對(duì)方停止執(zhí)行,以取得系統(tǒng)資源,但是沒(méi)有一方提前退出,就稱(chēng)為死鎖,下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • Springboot使用redisson實(shí)現(xiàn)分布式鎖的代碼示例

    Springboot使用redisson實(shí)現(xiàn)分布式鎖的代碼示例

    在實(shí)際項(xiàng)目中,某些場(chǎng)景下可能需要使用到分布式鎖功能,那么實(shí)現(xiàn)分布式鎖有多種方式,常見(jiàn)的如mysql分布式鎖、zookeeper分布式鎖、redis分布式鎖,本文介紹springboot如何使用redisson實(shí)現(xiàn)分布式鎖,需要的朋友可以參考下
    2023-06-06
  • 詳解如何使用IntelliJ IDEA生成UML圖

    詳解如何使用IntelliJ IDEA生成UML圖

    在軟件開(kāi)發(fā)中,UML(統(tǒng)一建模語(yǔ)言)是一種用于描述、構(gòu)建和文檔化軟件系統(tǒng)的圖形化語(yǔ)言,它幫助開(kāi)發(fā)者以可視化的方式理解系統(tǒng)的結(jié)構(gòu)和行為,手動(dòng)繪制 UML 圖可能既耗時(shí)又容易出錯(cuò),所以本文給大家介紹了如何使用IntelliJ IDEA生成UML圖,需要的朋友可以參考下
    2024-10-10
  • Java全面分析面向?qū)ο笾鄳B(tài)

    Java全面分析面向?qū)ο笾鄳B(tài)

    多態(tài)就是指程序中定義的引用變量所指向的具體類(lèi)型和通過(guò)該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類(lèi)中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定
    2022-04-04
  • java serialVersionUID解決序列化類(lèi)版本不一致問(wèn)題面試精講

    java serialVersionUID解決序列化類(lèi)版本不一致問(wèn)題面試精講

    這篇文章主要為大家介紹了serialVersionUID解決序列化類(lèi)版本不一致問(wèn)題的面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10

最新評(píng)論

南投市| 本溪市| 铅山县| 广汉市| 慈溪市| 东明县| 桂东县| 林州市| 恩平市| 利津县| 安顺市| 康定县| 鄂托克前旗| 康马县| 突泉县| 西丰县| 紫金县| 厦门市| 营山县| 孟州市| 顺昌县| 高雄市| 双鸭山市| 澄江县| 临沂市| 德格县| 秦皇岛市| 萍乡市| 长顺县| 介休市| 岢岚县| 尤溪县| 宁波市| 南安市| 松原市| 永定县| 德化县| 汪清县| 昭苏县| 内乡县| 郑州市|