java实现MD5的加密
来源:互联网 发布:淘宝卖家互刷平台 编辑:程序博客网 时间:2024/06/04 20:19
引入
MD5的来源
1.在各种应用系统中,如果需要设置账户,那么就会涉及到储存用户账户信息的问题,为了保证所储存账户信息的安全,一般就会使用到MD5进行加密储存。那么我们得的搞清楚什么是MD5。
2. MD5其全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。是让大容量信息在用数字签名软件签署私人密匙前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。不管是MD2、MD4还是MD5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。虽然这些算法的结构或多或少有些相似,但MD2的设计与MD4和MD5完全不同,那是因为MD2是为8位机器做过设计优化的,而MD4和MD5却是面向32位的电脑。这三个算法的描述和C语言源代码在Internet RFCs 1321中有详细的描述,这是一份最权威的文档,由Ronald L. Rivest在1992年8月向IETF提交。
3. MD5 其实在我们生活中是很常用的,似乎你并没有注意到,当你下载了一个镜像之后,你会发现下载页面还提供了一组 MD5 值,那么这组 MD5 值是用来做什么的呢?了解了 MD5 的作用之后,你就不难想到,MD5 是用来验证文件的一致性的,当你下载好镜像之后,你需要对该镜像做一次 MD5 的校验,得到的 MD5 值与下载页面提供的 MD5 值进行对比,以此来验证该镜像是否被篡改。
MD5 算法具有很多特点:
- 压缩性:任意长度的数据,算出的MD5值长度都是固定的。
- 容易计算:从原数据计算出MD5值很容易。
- 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
- 弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
- 强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。
消息摘要简介
一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组)。消息摘要是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前广泛使用的算法有MD4、MD5、SHA-1。
对字符串进行MD5处理:
加密及验证过程:
package com.lh.MD;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.Arrays;/** * MD加密 * @author huan * */public class MD5 { private static final String HEX_NUMS_STR = "0123456789ABCDEF"; private static final Integer SALT_LENGTH = 12; /** * 将16进制字符串转换成字节数组 * * @param hex * @return */ public static byte[] hexStringToByte(String hex) { int len = (hex.length() / 2); byte[] result = new byte[len]; char[] hexChars = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4 | HEX_NUMS_STR.indexOf(hexChars[pos + 1])); } return result; } /** * 将指定byte数组转换成16进制字符串 * * @param b * @return */ public static String byteToHexString(byte[] b) { StringBuffer hexString = new StringBuffer(); for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } hexString.append(hex.toUpperCase()); } return hexString.toString(); } /** * 验证口令是否合法 * * @param password * @param passwordInDb * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static boolean validPassword(String password, String passwordInDb) throws NoSuchAlgorithmException, UnsupportedEncodingException { // 将16进制字符串格式口令转换成字节数组 byte[] pwdInDb = hexStringToByte(passwordInDb); // 声明盐变量 byte[] salt = new byte[SALT_LENGTH]; // 将盐从数据库中保存的口令字节数组中提取出来 System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH); // 创建消息摘要对象 MessageDigest md = MessageDigest.getInstance("MD5"); // 将盐数据传入消息摘要对象 md.update(salt); // 将口令的数据传给消息摘要对象 md.update(password.getBytes("UTF-8")); // 生成输入口令的消息摘要 byte[] digest = md.digest(); // 声明一个保存数据库中口令消息摘要的变量 byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH]; // 取得数据库中口令的消息摘要 System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length); // 比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同 if (Arrays.equals(digest, digestInDb)) { // 口令正确返回口令匹配消息 return true; } else { // 口令不正确返回口令不匹配消息 return false; } } /** * 获得加密后的16进制形式口令 * * @param password * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static String getEncryptedPwd(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { // 声明加密后的口令数组变量 byte[] pwd = null; // 随机数生成器 SecureRandom random = new SecureRandom(); // 声明盐数组变量 byte[] salt = new byte[SALT_LENGTH]; // 将随机数放入盐变量中 random.nextBytes(salt); // 声明消息摘要对象 MessageDigest md = null; // 创建消息摘要 md = MessageDigest.getInstance("MD5"); // 将盐数据传入消息摘要对象 md.update(salt); // 将口令的数据传给消息摘要对象 md.update(password.getBytes("UTF-8")); // 获得消息摘要的字节数组 byte[] digest = md.digest(); // 因为要在口令的字节数组中存放盐,所以加上盐的字节长度 pwd = new byte[digest.length + SALT_LENGTH]; // 将盐的字节拷贝到生成的加密口令字节数组的前12个字节, // 以便在验证口令时取出盐 System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH); // 将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节 System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length); // 将字节数组格式加密后的口令转化为16进制字符串格式的口令 return byteToHexString(pwd); }}
测试代码:
package com.lh.MD;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;import java.util.HashMap;import java.util.Map;/** * 测试 * @author huan * */public class Test { private static Map<String, String> users = new HashMap<String, String>(); public static void main(String[] args) { String userName = "lh"; String password = "123"; registerUser(userName, password); userName = "ll"; password = "456"; registerUser(userName, password); String loginUserId = "lh"; String pwd = "123"; try { if (loginValid(loginUserId, pwd)) { System.out.println("欢迎登陆!!!"); } else { System.out.println("口令错误,请重新输入!!!"); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * 注册用户 * * @param userName * @param password */ public static void registerUser(String userName, String password) { String encryptedPwd = null; try { encryptedPwd = MD5.getEncryptedPwd(password); users.put(userName, encryptedPwd); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * 验证登陆 * * @param userName * @param password * @return * @throws UnsupportedEncodingException * @throws NoSuchAlgorithmException */ public static boolean loginValid(String userName, String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { String pwdInDb = (String) users.get(userName); if (null != pwdInDb) { // 该用户存在 return MD5.validPassword(password, pwdInDb); } else { System.out.println("不存在该用户!!!"); return false; } }}
结果:
- Java实现的MD5加密
- java实现的md5加密
- java实现MD5的加密
- MD5加密的Java实现
- MD5 JAVA 加密 实现
- Java实现MD5加密
- Java 实现MD5加密
- Java实现MD5加密
- MD5实现加密 java
- Java实现MD5加密
- java 实现md5加密
- Java实现md5加密
- Java实现MD5加密
- JAVA实现MD5加密
- java实现MD5加密
- java实现MD5加密
- java实现:md5加密
- java实现MD5加密
- Kafka相关技术文档
- FTP命令大全
- R语言中ifelse/which/%in%的用法
- Spring MVC 拦截器配置及使用(包括静态资源的处理)
- 用Python建立最简单的web服务器
- java实现MD5的加密
- UE4人物基本移动蓝图
- arm GIC介绍之二
- pip 换源、安装、升级,pip超时,报错 解决方案
- Android拍照或从相册中取照片
- 访问对象
- Freemarker入门-用Maven构建
- [译] iOS 11:机器学习人人有份
- java1.8学习demo