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 交通频道 作文范文 初二学生入团申请书1000字 如果有一天我们真的不再相见,我会用我的方式去想你 小学五年级作文350字:感谢老师 学习“邳州现象”心得体会 谁说我与这个城市格格不入? 区经促局2016年依法行政工作报告 乒乓球作文800字 疼爱的层次 23岁的时候,会是什么样子? 三年级班干部竞选演讲稿作文200字 悠悠小猪 车间党员红旗责任区上半年工作汇报 追忆星空作文1300字 大海里翻了的豆腐船 期待成为你的好友 大学生假期实习报告范文 为人民服务永存——观《张思德》有感(学习心得) 僵脖子大土豆 区建设局局长个人先进事迹材料 “三严三实”专题教育党课报告(审计局长) 往事作文200字 机电一体化职业规划 时光如诗 坚韧与顽强的作文 潇洒作文1000字 播撒诚信的种子作文450字 向考验发起挑战 演绎着青春活力的舞台 小学六年级作文100字:梅花 我的秘密基地550字 会计工作总结2017 不想离开作文450字 你是一种气质 我的承诺作文100字 我发现微笑的美丽 我终于学会了作文 送沈少府之任淮南 婚礼主持|传统的中式婚礼礼仪 你可以妖魔高中你不可以妖魔我 让我最难忘的一句名言作文600字 独恋上静静的夜 人生如茶 精美的散文 温暖就是那么简单作文 童话大王读后感5篇 “凶鬼子”爸爸 抒发爱国情怀的诗句 雪花,雪花 爱情非主流感人话语 活泼的小兔子

Copyright © 2016 phpStudy |