Java实现MD5加密及解密的代码实例分享


基础:MessageDigest类的使用

其实要在Java中完成MD5加密,MessageDigest类大部分都帮你实现好了,几行代码足矣:

/**
 * 对字符串md5加密
 *
 * @param str
 * @return
 */
import java.security.MessageDigest;
public static String getMD5(String str) {
 try {
  // 生成一个MD5加密计算摘要
  MessageDigest md = MessageDigest.getInstance("MD5");
  // 计算md5函数
  md.update(str.getBytes());
  // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
  // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
  return new BigInteger(1, md.digest()).toString(16);
 } catch (Exception e) {
  throw new SpeedException("MD5加密出现错误");
 }
}

进阶:加密及解密类
Java实现MD5加密以及解密类,附带测试类,具体见代码。

MD5加密解密类——MyMD5Util,代码如下

package com.zyg.security.md5;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

public class MyMD5Util {
 
 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);
 }
}

测试类——Client,代码如下:

package com.zyg.security.md5;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

public class Client {
 private static Map users = new HashMap();
 
 public static void main(String[] args){
 String userName = "zyg";
 String password = "123";
 registerUser(userName,password);
 
 userName = "changong";
 password = "456";
 registerUser(userName,password);
 
 String loginUserId = "zyg";
 String pwd = "1232";
 try {
  if(loginValid(loginUserId,pwd)){
  System.out.println("欢迎登陆!!!");
  }else{
  System.out.println("口令错误,请重新输入!!!");
  }
 } catch (NoSuchAlgorithmException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } 
 }
 
 /**
 * 注册用户
 * 
 * @param userName
 * @param password
 */
 public static void registerUser(String userName,String password){
 String encryptedPwd = null;
 try {
  encryptedPwd = MyMD5Util.getEncryptedPwd(password);
  
  users.put(userName, encryptedPwd);
  
 } catch (NoSuchAlgorithmException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  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 MyMD5Util.validPassword(password, pwdInDb);
 }else{
  System.out.println("不存在该用户!!!");
  return false;
 }
 }
}



相关阅读:
jQuery对于显示和隐藏等常用状态的判断方法
PHP中iconv函数知识汇总
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
jQuery结合HTML5制作的爱心树表白动画
JavaScript实现MIPS乘法模拟的方法
修改mysql默认字符集的两种方法详细解析
JS中Location使用详解
PHP的反射类ReflectionClass、ReflectionMethod使用实例
举例讲解Java中的Stream流概念
酷! 不同风格页面布局幻灯片特效js实现
jQuery实现内容定时切换效果完整实例
Win10预览版10122 官方已知三个重要bug汇总
Html5实现二维码扫描并解析
用php实现选择排序的解决方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 医务护理检讨书 幼儿园中班上学期教师个人总结 愿做花下泥——写给默默的芋头 ★☆ 2015年小学图书室工作计划 琴殇(十二)作文1500字 美丽的茶菊花 同志考核材料 闭口不言造句 小品:饮水思源 硕士研究生求职面试的自我介绍 初中初一作文1000字:辉煌 城管局书记述职报告范文 “解放思想、树立科学发展观”领导干部培训班学习心得 2016年创业服务年个人心得体会 爱看戏的老人 在市“视觉健康光明行”百场戏剧下乡活动启动仪式上的讲话 教育教学经验总结(职评材料) 开业对联对照表 身份证遗失补办证明 我得了双百作文400字 原来最艰难的不是放手 2011年残联工作总结 我最喜欢的水果——哈密瓜 我将我心。。。。。。 电脑绘图_关于学习电脑画图的小学生日记500字 月满西楼(外一首) 《意林》读后感250字 2014最新工作计划范文 天真作文500字 2015小学老师工作总结 【短篇小说】顶梁柱(6) 给爸爸妈妈的信700字 我们能为世界做什么 伤感心疼的爱情始终要终结 县等级医院评审工作的总结报告 小学地方课程实施方案 隔山隔水,也隔情 吴邦国在乌兹别克斯坦最高会议的演讲稿 初中初二作文800字:我们美丽的新“书架” 小学生励志故事《狼与狈》 受伤的小树_350字 刘长东 [寂寞的烟在我世界里 ] 地球的呼吁书700字 游天心阁作文800字 对加强上市公司虚假财务报告监管的理性思考 大哭一场吧 我一定会努力的,一定 一定作文800字 小学四年级作文450字:与树有约 夏天的风采_关于描写夏天的小学生作文600字 我为奥运添光彩作文 高中高三作文2500字:赤着脚的女孩

Copyright © 2016 phpStudy |