面试突击91:MD5 加密安全吗?

news/2024/4/19 19:54:05/文章来源:https://www.cnblogs.com/vipstone/p/16804025.html

MD5 是 Message Digest Algorithm 的缩写,译为信息摘要算法,它是 Java 语言中使用很广泛的一种加密算法。MD5 可以将任意字符串,通过不可逆的字符串变换算法,生成一个唯一的 MD5 信息摘要,这个信息摘要也就是我们通常所说的 MD5 字符串。那么问题来了,MD5 加密安全吗?

这道题看似简单,其实是一道送命题,很多人尤其是一些新入门的同学会觉得,安全啊,MD5 首先是加密的字符串,其次是不可逆的,所以它一定是安全的。如果你这样回答,那么就彻底掉进面试官给你挖好的坑了。

为什么呢?因为答案是“不安全”,而不是“安全”

1.彩虹表

MD5 之所以说它是不安全的,是因为每一个原始密码都会生成一个对应的固定密码,也就是说一个字符串生成的 MD5 值是永远不变的。这样的话,虽然它是不可逆的,但可以被穷举,而穷举的“产品”就叫做彩虹表。

什么是彩虹表?

彩虹表是一个用于加密散列函数逆运算的预先计算好的表, 为破解密码的散列值(或称哈希值、微缩图、摘要、指纹、哈希密文)而准备。 一般主流的彩虹表都在 100G 以上。这样的表常常用于恢复由有限集字符组成的固定长度的纯文本密码。这是空间/时间替换的典型实践,比每一次尝试都计算哈希的暴力破解处理时间少而储存空间多,但却比简单的对每条输入散列翻查表的破解方式储存空间少而处理时间多。

简单来说,彩虹表就是一个很大的,用于存放穷举对应值的数据表。 以 MD5 为例,“1”的 MD5 值是“C4CA4238A0B923820DCC509A6F75849B”,而“2”的 MD5 值是“C81E728D9D4C2F636F067F89CC14862C”,那么就会有一个 MD5 的彩虹表是这样的:

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

大家想想,如果有了这张表之后,那么我就可以通过 MD5 的密文直接查到原始密码了,所以说数据库如果只使用 MD5 加密,这就好比用了一把插了钥匙的锁一样不安全。

2.解决方案

想要解决以上问题,我们需要引入“加盐”机制。

盐(Salt):在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。

说的通俗一点“加盐”就像炒菜一样,放不同的盐,炒出菜的味道就是不同的,咱们之前使用 MD5 不安全的原因是,每个原始密码所对应的 MD5 值都是固定的,那我们只需要让密码每次通过加盐之后,生成的最终密码都不同,这样就能解决加密不安全的问题了

3.实现代码

加盐是一种手段、是一种解决密码安全问题的思路,而它的实现手段有很多种,我们可以使用框架如 Spring Security 提供的 BCrypt 进行加盐和验证,当然,我们也可以自己实现加盐的功能。

本文为了让大家更好的理解加盐的机制,所以我们自己来动手来实现一下加盐的功能。
实现加盐机制的关键是在加密的过程中,生成一个随机的盐值,而且随机盐值尽量不要重复,这时,我们就可以使用 Java 语言提供的 UUID(Universally Unique Identifier,通用唯一识别码)来作为盐值,这样每次都会生成一个不同的随机盐值,且永不重复
加盐的实现代码如下:

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) {// 随机盐值 UUIDString salt = UUID.randomUUID().toString().replaceAll("-", "");// 密码=md5(随机盐值+密码)String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());return salt + "$" + finalPassword;}
}

从上述代码我们可以看出,加盐的实现具体步骤是:

  1. 使用 UUID 产生一个随机盐值;
  2. 将随机盐值 + 原始密码一起 MD5,产生一个新密码(相同的原始密码,每次都会生成一个不同的新密码);
  3. 将随机盐值 + "$"+上一步生成的新密码加在一起,就是最终生成的密码。

那么,问题来了,既然每次生成的密码都不同,那么怎么验证密码是否正确呢?
要验证密码是否正确的关键是需要先获取盐值,然后再使用相同的加密方式和步骤,生成一个最终密码和和数据库中保存的加密密码进行对比,具体实现代码如下:

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) {// 随机盐值 UUIDString salt = UUID.randomUUID().toString().replaceAll("-", "");// 密码=md5(随机盐值+密码)String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());return salt + "$" + finalPassword;}/*** 解密* @param password       要验证的密码(未加密)* @param securePassword 数据库中的加了盐值的密码* @return 对比结果 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];// 使用同样的加密算法和随机盐值生成最终加密的密码password = DigestUtils.md5DigestAsHex((slat + password).getBytes());if (finalPassword.equals(password)) {result = true;}}}return result;}
}

总结

只是简单的使用 MD5 加密是不安全的,因为每个字符串都会生成固定的密文,那么我们就可以使用彩虹表将密文还原出来,所以它不是安全的。想要解决这个问题,我们需要通过加盐的手段,每次生成一个不同的密码,就把这个问题解决了。

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java面试真题解析

面试合集:https://gitee.com/mydb/interview

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_25473.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高可用linux 服务器搭建

最原始的服务部署,为单点部署,即直接把服务部署在一个服务器上。如果服务器出现故障,或者服务因为某个异常而挂掉,则服务就会发生中断。单点部署出现故障的概率最高。 后来,出现了网关,比如 nginx kong 等。如下图所示:这样,所有客户请求都会经过网关,再由网关转发到各…

python的opencv操作记录(七)——短时傅里叶变换(stft)

文章目录DCT-傅立叶变换的局限性STFT 短时傅里叶变换从另一个角度来理解图像的“时域”数据看看fs和t这两个参数再看看怎么划分窗口最后看另外两个出参Zxx返回结构图像的stftDCT-傅立叶变换的局限性 接上一篇DCT的文章,DCT只提取了整个信号域的频率信息&#xff0c…

Python——HTTP代理 Proxy

大佬勿喷 链接: https://pan.baidu.com/s/1Wm0JepiZa9iPn4WoQU3Qdg 提取码: p09g

【计算机毕业设计】基于微信小程序的校园生活服务平台

提供了一些今年最新计算机毕业设计源代码、文档及帮助指导,公众号:一点毕设,领取更多毕设资料。 一.课题概述 随着互联网时代的到来,移动端应用的发展十分迅猛,校园服务类应用 也是不计其数。但大多功能单一&#xf…

Word处理控件Aspose.Words功能演示:使用 Java 将 RTF 转换为 PDF

RTF 格式由 Microsoft 引入,用于创建富文本文档。RTF 的互操作性使得在不同的 Microsoft 产品以及异构操作系统之间交换内容成为可能。但是,有时可能需要将 RTF 转换为 PDF 以用于打印、共享或其他目的。因此,本文介绍了 如何使用 Java 以编程…

干净的代码——一种实用的方法

在对干净代码进行了一些讨论之后,我决定在一篇文章中总结最重要的事情。因为网上有很多关于清洁代码的帖子和信息,我认为一篇新的文章谈论它只是解释一些原则是不值得的。在本文中,我将尝试为您提供清洁代码的实用方法。我不会深入理论&#…

海康大华等录像机、摄像头无法通过GB28181注册到LiveGBS国标平台问题排查方法

LiveGBS常见问题-海康大华宇视华为NVR摄像头无法注册到平台国标平台看不到设备的时候如何抓包及排查1、设备注册后查看不到1.1、防火墙排查1.2、端口排查1.3、IP地址排查1.4、设备TCP/IP配置排查1.5、设备多网卡排查1.6、设备接入配置参数排查1.7、设备尝试修改本地SIP端口1.8、…

Biotin-PEG-Alk,Biotin-PEG-Alkyne,生物素-聚乙二醇-炔烃科研用试剂供应

An English name:Biotin-PEG-Alk,Biotin-PEG-Alkyne Chinese name:生物素-聚乙二醇-炔烃 Item no:X-GF-0267-10k CAS:N/A Formula:N/A MW:Biotin-PEG1-Alkyne/Biotin-PEG2-Alkyne/Biotin-P…

uni-app实战之单击菜单发布->H5的Promise 化在工程项目的实战演练项目心得

H5 开发注意 H5发布到服务器注意: 配置发布后的路径(在网站的根目录中发布是可选的),例如发布网站的路径为www.xxx Com/html5,在manifest中编辑json文件中的h5节点,并将base属性添加到路由器下的html5 单…

基于PHP的蔬菜价格查询管理系统设计与实现

目 录 1 引言 1 1.1 课题背景与意义 1 1.2 课题现状与可研究性 1 1.3 本论文研究内容和结构安排 1 2 系统基础概述 2 2.1 软件开发环境 2 2.2 L,Linux操作系统 2 2.3 A,Apache服务器 2 2.4 M,Mysql数据库 3 2.5 P,PHP语言 3 2.5.1…

EXCEL表格-VLOOKUP多对一结果匹配方法(通配符)

❤关注我,不迷路❤ 点击进入EXCEL综合应用场景专栏 在实际使用场景中,通过一个值去匹配另一个值的案例很常见,比如一份学校的信息表,通过姓名查找班级、家长姓名等,均用VLOOKUP函数可以实现,正向查找、逆…

【Coel.学习笔记】莫比乌斯反演

冷知识:百度百科里甚至没有对反演的准确定义……闲话 记得在差不多一年前写扩展欧拉定理的时候我提了一句这周终于把古代猪文搞定了,数论这块的内容就只剩个博弈论了 别提莫比乌斯反演之类的东西,我不想搞甚至刚开始写的时候还笔误把莫反写成了莫队…… 转眼一年过去了,来填…

leetcode 123买卖股票的最佳时机III

买卖股票的最佳时机III 动态规划-分两小组分别计算&#xff08;超时&#xff09; class Solution { public:int partprofit( vector<int>& prices , int start , int end ){if((end-start)<1) return 0;vector<int> dp(end - start , 0);int min prices[s…

视觉检测工作台设计

目 录 摘 要 I Abstract II 第1章 引言 1 1.1研究背景及意义 1 1.2国内外研究现状 2 第2章 总体方案的确定 4 2.1方案拟定 4 2.1.1机械结构 4 2.1. 2控制工艺要求 5 2.1. 3总体方案 5 2.2 设计参数 7 第3章 视觉检测工作台机械系统设计 8 3.1 X-Y数控工作台总体方案的确定 8 3.…

微信公众号查题搜题平台

微信公众号查题搜题平台 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&#xf…

物联网、区块链、元宇宙和虚拟数字人离普罗大众有多远?

首先&#xff0c;我们最早理解的数字人就是数字虚拟的一个假人&#xff0c;可能看起来很像二次元玩偶的样子。今天我觉得数字人是一种虚拟的数字身份&#xff0c;无所谓你的形象是仿真或是任何形象&#xff0c;包括你在现实中无法实现的形象&#xff0c;你在梦想中所渴望的概念…

【数据结构与算法分析】0基础带你学数据结构与算法分析01--基础数学知识

&#x1f353;个人主页&#xff1a;个人主页 &#x1f4ac;推荐一款模拟面试、刷题神器&#xff0c;从基础到大厂面试题&#xff1a;点击跳转进入网站 &#x1f4e9;如果你想学习算法&#xff0c;以及一些语言基础的知识&#xff0c;那就来这里&#xff1a;​​​​刷题网站 跟…

无公网IP远程黑群晖【内网穿透】

无公网IP远程黑群晖【内网穿透】1. 安装cpolar群晖套件2、打开cpolar套件3. 创建远程访问隧道4. 获取公网地址访问由于黑群晖没办法用QuickConnect&#xff0c;洗白也比较麻烦&#xff0c;所以这里用内网穿透的方法来实现远程。 这里推荐一款免费不限制流量的内网穿透工具cpol…

二维数组(理论)

二维数组的定义和操作 学习目标&#xff1a; 1、理解二维数组及其存储结构。 2、掌握二维数组的初始化、输入输出等基本操作。 引入&#xff1a; 由前面介绍可知&#xff0c;一维数组的元素可以是任何基本数据类型&#xff0c;也可以是结构体。那么&#xff0c;如果一维数组的…

新闻订阅及新闻内容展示系统(Python+Django+scrapy)

目录 摘 要 1 Abstract 2 第一章 引言 3 1.1 项目的背景和意义 3 1.2.1 个性化新闻服务现状 4 1.2.2 网络爬虫研究现状 4 1.2.3 项目的范围和预期结果 4 第二章 技术与原理 5 2.1 技术选型 5 2.2 相关原理介绍 7 第三章 系统需求分析 10 3. 1 新闻订阅系统用例析取 10 3.2 新闻…