MD5收集整理
MD5如何生成的

生成MD5
1.通过摘要生成MD5
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(input.getBytes(StandardCharsets.UTF_8));
byte[] hashBytes = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
2.使用Google的Guava生成MD5
- 添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
- 生成代码
// com.google.common.hash.Hashing.md5()
// If you must interoperate with a system that requires MD5, then use this method, despite its deprecation. But if you can choose your hash function, avoid MD5, which is neither fast nor secure. As of January 2017, we suggest:
// For security: Hashing.sha256() or a higher-level API.
// For speed: Hashing.goodFastHash(int), though see its docs for caveats.
HashFunction hashFunction = Hashing.md5();
HashCode hash = hashFunction.hashString(input, StandardCharsets.UTF_8);
return hash.toString();
3.使用Appach的commons生成MD5
- 添加依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
- 生成代码
String md5 = DigestUtils.md5Hex( input );
return md5;
加盐MD5
为什么加盐
彩虹表是一个用于加密散列函数逆运算的预先计算好的表, 常用于破解加密过的密码散列。一般主流的彩虹表都在100G以上。 查找表常常用于包含有限字符固定长度纯文本密码的加密。这是以空间换时间的典型实践, 在每一次尝试都计算的暴力破解中使用更少的计算能力和更多的储存空间,但却比简单的每个输入一条散列的翻查表使用更少的储存空间和更多的计算性能。使用加盐的KDF函数可以使这种攻击难以实现。
什么是盐
- 密码加盐
- 本质就是增加要加密内容的单一性,使用复杂。比如:只对密码加密->对用户名和密码加密(一个不对全不对)->对用户名和密码再加随机数加密(为了验证,最终还是要报随机数的位置确定,验证前删除掉)
如何加盐
加盐示例代码
public static String createMd5WithSalt(String input) throws NoSuchAlgorithmException {
// MessageDigest instance for MD5
MessageDigest md = MessageDigest.getInstance("MD5");
// Generate the random salt
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
md.update(salt);
md.update(input.getBytes(StandardCharsets.UTF_8));
byte[] hashBytes = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
加盐并能重复验证
一般一个系统会使用一个固定格式的盐 如用户名加密
也有使用固定位数的盐的,如把盐按一定规律插入到生面的md5中,验证时从中取出盐,然后再校验
private static Integer SALT_LENGTH = 16;
private static Integer SALT_MD5_LENGTH = 48;
private static Integer STEP_LENGTH = 3;
public static String createMd5WithSalt(String input) throws NoSuchAlgorithmException {
// 生成一个16位的随机数
SecureRandom random = new SecureRandom();
StringBuilder sBuilder = new StringBuilder(16);
sBuilder.append(random.nextInt(66888888)).append(random.nextInt(66888888));
int len = sBuilder.length();
if (len < SALT_LENGTH) {
for (int i = 0; i < SALT_LENGTH - len; i++) {
sBuilder.append("0");
}
}
// 生成最终的加密盐
String Salt = sBuilder.toString();
String saltMd5 = createMd5(input + Salt);
char[] cs = new char[SALT_MD5_LENGTH];
for (int i = 0; i < SALT_MD5_LENGTH; i += STEP_LENGTH) {
cs[i] = saltMd5.charAt(i / 3 * 2);
char c = Salt.charAt(i / 3);
cs[i + 1] = c;
cs[i + 2] = saltMd5.charAt(i / 3 * 2 + 1);
}
return String.valueOf(cs);
}
public static boolean verifyMd5WithSalt(String input, String md5str) throws NoSuchAlgorithmException {
char[] cs1 = new char[32];
char[] cs2 = new char[16];
for (int i = 0; i < SALT_MD5_LENGTH; i += STEP_LENGTH) {
cs1[i / 3 * 2] = md5str.charAt(i);
cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2);
cs2[i / 3] = md5str.charAt(i + 1);
}
String Salt = new String(cs2);
return createMd5(input + Salt).equals(String.valueOf(cs1));
}
// 使用
// 加盐
String md5WithSalt = MessageDigestCreate.createMd5WithSalt("测试md5");
System.out.println(md5WithSalt);
System.out.println(MessageDigestCreate.verifyMd5WithSalt("测试md5",md5WithSalt));
/**
125214383c3b755320902731b46d79344914f2199c786272
true
*/
- 建议使用安全随机数。
- 其它几种方式加盐同理,只是生面md5的来源不同
- 源码
MD5收集整理的更多相关文章
- php : 收集整理的非常有用的函数
项目中经常会需要一些让人头疼的函数,作为开发者应该整理一个自己的函数库,在需要之时复制过来即可.以下是收集整理数十个PHP项目中常用的函数 1.PHP加密解密 PHP加密和解密函数可以用来加密一些有用 ...
- 收集整理的非常有用的PHP函数
原文:收集整理的非常有用的PHP函数 项目中经常会需要一些让人头疼的函数,作为开发者应该整理一个自己的函数库,在需要之时复制过来即可.本文作者收集整理数十个PHP项目中常用的函数,保证能正常运行,你只 ...
- [转帖]PKI技术原理(收集 整理 归纳)
PKI技术原理(收集 整理 归纳) https://blog.51cto.com/3layer/20430 总结归纳的 灰常好.. 7layer关注8人评论39427人阅读2007-03-14 11: ...
- 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发
[原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文 http: ...
- 最常用的PHP正则表达式收集整理
最常用的PHP正则表达式收集整理 提交 我的评论 加载中 已评论 最常用的PHP正则表达式收集整理 2015-03-20 PHP100中文网 PHP100中文网 PHP100中文网 微信号 功能介绍 ...
- 【Android源代码下载】收集整理android界面UI效果源码
在Android开发中,Android界面UI效果设计一直都是很多童鞋关注的问题,今天给大家分享下大神收集整理的多个android界面UI效果,都是源码,都是干货,贡献给各位网友! 话不多说,直接上效 ...
- 超常用的PHP正则表达式收集整理
以下就是对超常用的PHP正则表达式进行的收集整理,为了方便大家更快更好的掌握php正则表达式. 一.表单验证匹配验证账号,字母开头,允许 5-16 字节,允许字母数字下划线:^[a-zA-Z][a-z ...
- amoeba-mysql配置安装(收集整理)
本文收集整理自: Amoeba搞定mysql主从读写分离 http://blog.chinaunix.net/uid-20639775-id-154600.html Amoeba非常好用的mysql集 ...
- 原生JS研究:学习jquery源码,收集整理常用JS函数
原生JS研究:学习jquery源码,收集整理常用JS函数: 1. JS获取原生class(getElementsByClass) 转自:http://blog.csdn.net/kongjiea/ar ...
随机推荐
- @RequestMapping 用法详解之地址映射(转)
这段时间项目中用到了RESTful模式来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没有加任何注解),查看了提交方式为application/js ...
- 基于vue实现搜索高亮关键字
有一个需求是在已有列表中搜索关键词,然后在列表中展示含有相关关键字的数据项并且对关键字进行高亮显示,所以该需求需要解决的就两个问题: 1.搜索关键词过滤列表数据 2.每个列表高亮关键字 ps: 此问题 ...
- Splitting into digits CodeForce#1104A
题目链接:Splitting into digits 题目原文 Vasya has his favourite number
- Flask学习之旅--用 Python + Flask 制作一个简单的验证码系统
一.写在前面 现在无论大大小小的网站,基本上都会使用验证码,登录的时候要验证,下载的时候要验证,而使用的验证码也从那些简简单单的字符图形验证码“进化”成了需要进行图文识别的验证码.需要拖动滑块的滑动验 ...
- [Next] 初见next.js
next 简介 Next.js 是一个轻量级的 React 服务端渲染应用框架 next 特点 默认情况下由服务器呈现 自动代码拆分可加快页面加载速度 简单的客户端路由(基于页面) 基于 Webpac ...
- 从ASP.Net Core Web Api模板中移除MVC Razor依赖项
前言 :本篇文章,我将会介绍如何在不包括MVC / Razor功能和包的情况下,添加最少的依赖项到ASP.NET Core Web API项目中. 一.MVC VS WebApi (1)在ASP. ...
- freemarker常用属性
1.th:action 定义后台控制器的路径,类似<form>标签的action属性. 示例如下. <form id="login" th:action=&quo ...
- 异步Promise及Async/Await最完整入门攻略
一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪圈, ...
- Angular template ng-template/container/content
1. ng-template 形式:<ng-template>...</ng-template> 默认ng-template中的内容会隐藏; 可通过[ngIf]来控制内容显示隐 ...
- 一条SQL查询语句是如何执行的?
本篇文章将通过一条 SQL 的执行过程来介绍 MySQL 的基础架构. 首先有一个 user_info 表,表里有一个 id 字段,执行下面这条查询语句: select * from user_inf ...