首页 > 代码库 > Java_util_01_MD5加密

Java_util_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 block30  e.printStackTrace();31  } catch (UnsupportedEncodingException e) {32  // TODO Auto-generated catch block33  e.printStackTrace();34  } 35  }36   37  /**38  * 注册用户39  * 40  * @param userName41  * @param password42  */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 block52  e.printStackTrace();53  } catch (UnsupportedEncodingException e) {54  // TODO Auto-generated catch block55  e.printStackTrace();56  }57  }58   59  /**60  * 验证登陆61  * 62  * @param userName63  * @param password64  * @return65  * @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

 

Java_util_01_MD5加密