JavaUtil_01_MD5加密

一、百度翻译MD5工具类

昨天做java微信开发,引用百度翻译API给公众号添加翻译功能时,需要使用MD5生成签名。注意,使用MD5生成签名后一定要转成小写,不然百度翻译后台不会认你这个签名的,会报无效签名的错误。

百度给出的MD5加密算法示例:

  1 package com.baidu.translate.demo;
  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileNotFoundException;
  6 import java.io.IOException;
  7 import java.io.InputStream;
  8 import java.security.MessageDigest;
  9 import java.security.NoSuchAlgorithmException;
 10 
 11 /**
 12  * MD5编码相关的类
 13  * 
 14  * @author wangjingtao
 15  * 
 16  */
 17 public class MD5 {
 18     // 首先初始化一个字符数组,用来存放每个16进制字符
 19     private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
 20             'e', 'f' };
 21 
 22     /**
 23      * 1.获得一个字符串的MD5值
 24      * 
 25      * @param input 输入的字符串
 26      * @return 输入字符串的MD5值
 27      * 
 28      */
 29     public static String md5(String input) {
 30         if (input == null)
 31             return null;
 32 
 33         try {
 34             // 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
 35             MessageDigest messageDigest = MessageDigest.getInstance("MD5");
 36             // 输入的字符串转换成字节数组
 37             byte[] inputByteArray = input.getBytes("utf-8");
 38             // inputByteArray是输入字符串转换得到的字节数组
 39             messageDigest.update(inputByteArray);
 40             // 转换并返回结果,也是字节数组,包含16个元素
 41             byte[] resultByteArray = messageDigest.digest();
 42             // 字符数组转换成字符串返回
 43             return byteArrayToHex(resultByteArray);
 44         } catch (NoSuchAlgorithmException e) {
 45             return null;
 46         }
 47     }
 48 
 49     /**
 50      * 2.获取文件的MD5值
 51      * 
 52      * @param file
 53      * @return
 54      */
 55     public static String md5(File file) {
 56         try {
 57             if (!file.isFile()) {
 58                 System.err.println("文件" + file.getAbsolutePath() + "不存在或者不是文件");
 59                 return null;
 60             }
 61 
 62             FileInputStream in = new FileInputStream(file);
 63 
 64             String result = md5(in);
 65 
 66             in.close();
 67 
 68             return result;
 69 
 70         } catch (FileNotFoundException e) {
 71             e.printStackTrace();
 72         } catch (IOException e) {
 73             e.printStackTrace();
 74         }
 75 
 76         return null;
 77     }
 78      //3.
 79     public static String md5(InputStream in) {
 80 
 81         try {
 82             MessageDigest messagedigest = MessageDigest.getInstance("MD5");
 83 
 84             byte[] buffer = new byte[1024];
 85             int read = 0;
 86             while ((read = in.read(buffer)) != -1) {
 87                 messagedigest.update(buffer, 0, read);
 88             }
 89 
 90             in.close();
 91 
 92             String result = byteArrayToHex(messagedigest.digest());
 93 
 94             return result;
 95         } catch (NoSuchAlgorithmException e) {
 96             e.printStackTrace();
 97         } catch (FileNotFoundException e) {
 98             e.printStackTrace();
 99         } catch (IOException e) {
100             e.printStackTrace();
101         }
102 
103         return null;
104     }
105     //4.字符数组转字符串
106     private static String byteArrayToHex(byte[] byteArray) {
107         // new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
108         char[] resultCharArray = new char[byteArray.length * 2];
109         // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
110         int index = 0;
111         for (byte b : byteArray) {
112             resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
113             resultCharArray[index++] = hexDigits[b & 0xf];
114         }
115 
116         // 字符数组组合成字符串返回
117         return new String(resultCharArray);
118 
119     }
120 
121 }
View Code

 

 

二、脚本之家MD5工具类

脚本之家关于MD5的讲解很详细,传送门http://www.jb51.net/article/86027.htm

1.对字符串进行MD5加密

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

 

2.MD5加解密工具类

(1)MD5加密以及解密类

  1 package com.zyg.security.md5;
  2  
  3 import java.io.UnsupportedEncodingException;
  4 import java.security.MessageDigest;
  5 import java.security.NoSuchAlgorithmException;
  6 import java.security.SecureRandom;
  7 import java.util.Arrays;
  8  
  9 public class MyMD5Util {
 10   
 11  private static final String HEX_NUMS_STR="0123456789ABCDEF";
 12  private static final Integer SALT_LENGTH = 12;
 13   
 14  /** 
 15  * 将16进制字符串转换成字节数组 
 16  * @param hex 
 17  * @return 
 18  */
 19  public static byte[] hexStringToByte(String hex) {
 20  int len = (hex.length() / 2);
 21  byte[] result = new byte[len];
 22  char[] hexChars = hex.toCharArray();
 23  for (int i = 0; i < len; i++) {
 24  int pos = i * 2;
 25  result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4
 26  | HEX_NUMS_STR.indexOf(hexChars[pos + 1]));
 27  }
 28  return result;
 29  }
 30  
 31   
 32  /**
 33  * 将指定byte数组转换成16进制字符串
 34  * @param b
 35  * @return
 36  */
 37  public static String byteToHexString(byte[] b) {
 38  StringBuffer hexString = new StringBuffer();
 39  for (int i = 0; i < b.length; i++) {
 40  String hex = Integer.toHexString(b[i] & 0xFF);
 41  if (hex.length() == 1) {
 42  hex = '0' + hex;
 43  }
 44  hexString.append(hex.toUpperCase());
 45  }
 46  return hexString.toString();
 47  }
 48   
 49  /**
 50  * 验证口令是否合法
 51  * @param password
 52  * @param passwordInDb
 53  * @return
 54  * @throws NoSuchAlgorithmException
 55  * @throws UnsupportedEncodingException
 56  */
 57  public static boolean validPassword(String password, String passwordInDb)
 58  throws NoSuchAlgorithmException, UnsupportedEncodingException {
 59  //将16进制字符串格式口令转换成字节数组
 60  byte[] pwdInDb = hexStringToByte(passwordInDb);
 61  //声明盐变量
 62  byte[] salt = new byte[SALT_LENGTH];
 63  //将盐从数据库中保存的口令字节数组中提取出来
 64  System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);
 65  //创建消息摘要对象
 66  MessageDigest md = MessageDigest.getInstance("MD5");
 67  //将盐数据传入消息摘要对象
 68  md.update(salt);
 69  //将口令的数据传给消息摘要对象
 70  md.update(password.getBytes("UTF-8"));
 71  //生成输入口令的消息摘要
 72  byte[] digest = md.digest();
 73  //声明一个保存数据库中口令消息摘要的变量
 74  byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];
 75  //取得数据库中口令的消息摘要
 76  System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length);
 77  //比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同
 78  if (Arrays.equals(digest, digestInDb)) {
 79  //口令正确返回口令匹配消息
 80  return true;
 81  } else {
 82  //口令不正确返回口令不匹配消息
 83  return false;
 84  }
 85  }
 86  
 87  
 88  /**
 89  * 获得加密后的16进制形式口令
 90  * @param password
 91  * @return
 92  * @throws NoSuchAlgorithmException
 93  * @throws UnsupportedEncodingException
 94  */
 95  public static String getEncryptedPwd(String password)
 96  throws NoSuchAlgorithmException, UnsupportedEncodingException {
 97  //声明加密后的口令数组变量
 98  byte[] pwd = null;
 99  //随机数生成器
100  SecureRandom random = new SecureRandom();
101  //声明盐数组变量
102  byte[] salt = new byte[SALT_LENGTH];
103  //将随机数放入盐变量中
104  random.nextBytes(salt);
105  
106  //声明消息摘要对象
107  MessageDigest md = null;
108  //创建消息摘要
109  md = MessageDigest.getInstance("MD5");
110  //将盐数据传入消息摘要对象
111  md.update(salt);
112  //将口令的数据传给消息摘要对象
113  md.update(password.getBytes("UTF-8"));
114  //获得消息摘要的字节数组
115  byte[] digest = md.digest();
116  
117  //因为要在口令的字节数组中存放盐,所以加上盐的字节长度
118  pwd = new byte[digest.length + SALT_LENGTH];
119  //将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐
120  System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);
121  //将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节
122  System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);
123  //将字节数组格式加密后的口令转化为16进制字符串格式的口令
124  return byteToHexString(pwd);
125  }
126 }
View Code

(2)测试类——Client

 1 package com.zyg.security.md5;
 2  
 3 import java.io.UnsupportedEncodingException;
 4 import java.security.NoSuchAlgorithmException;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7  
 8 public class Client {
 9  private static Map users = new HashMap();
10   
11  public static void main(String[] args){
12  String userName = "zyg";
13  String password = "123";
14  registerUser(userName,password);
15   
16  userName = "changong";
17  password = "456";
18  registerUser(userName,password);
19   
20  String loginUserId = "zyg";
21  String pwd = "1232";
22  try {
23  if(loginValid(loginUserId,pwd)){
24  System.out.println("欢迎登陆!!!");
25  }else{
26  System.out.println("口令错误,请重新输入!!!");
27  }
28  } catch (NoSuchAlgorithmException e) {
29  // TODO Auto-generated catch block
30  e.printStackTrace();
31  } catch (UnsupportedEncodingException e) {
32  // TODO Auto-generated catch block
33  e.printStackTrace();
34  } 
35  }
36   
37  /**
38  * 注册用户
39  * 
40  * @param userName
41  * @param password
42  */
43  public static void registerUser(String userName,String password){
44  String encryptedPwd = null;
45  try {
46  encryptedPwd = MyMD5Util.getEncryptedPwd(password);
47   
48  users.put(userName, encryptedPwd);
49   
50  } catch (NoSuchAlgorithmException e) {
51  // TODO Auto-generated catch block
52  e.printStackTrace();
53  } catch (UnsupportedEncodingException e) {
54  // TODO Auto-generated catch block
55  e.printStackTrace();
56  }
57  }
58   
59  /**
60  * 验证登陆
61  * 
62  * @param userName
63  * @param password
64  * @return
65  * @throws UnsupportedEncodingException 
66  * @throws NoSuchAlgorithmException 
67  */
68  public static boolean loginValid(String userName,String password) 
69  throws NoSuchAlgorithmException, UnsupportedEncodingException{
70  String pwdInDb = (String)users.get(userName);
71  if(null!=pwdInDb){ // 该用户存在
72  return MyMD5Util.validPassword(password, pwdInDb);
73  }else{
74  System.out.println("不存在该用户!!!");
75  return false;
76  }
77  }
78 }
View Code

 

posted @ 2017-08-11 09:44  shirayner  阅读(316)  评论(0编辑  收藏  举报