package com.xiang.test; 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進(jìn)制字符串轉(zhuǎn)換成字節(jié)數(shù)組 * * @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數(shù)組轉(zhuǎn)換成16進(jìn)制字符串 * * @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(); } /** * 驗(yàn)證口令是否合法 * * @param password * @param passwordInDb * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static boolean validPassword(String password, String passwordInDb) throws NoSuchAlgorithmException, UnsupportedEncodingException { // 將16進(jìn)制字符串格式口令轉(zhuǎn)換成字節(jié)數(shù)組 byte[] pwdInDb = hexStringToByte(passwordInDb); System.out.println("驗(yàn)證時的pwdInDb:"); for (byte b : pwdInDb) { System.out.print(b); } System.out.println(); System.out.println("驗(yàn)證時的pwdInDb end"); // 聲明鹽變量 byte[] salt = new byte[SALT_LENGTH]; // 將鹽從數(shù)據(jù)庫中保存的口令字節(jié)數(shù)組中提取出來 System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH); System.out.println("驗(yàn)證時的salt:"); for (byte b : salt) { System.out.print(b); } System.out.println(); System.out.println("驗(yàn)證時的salt end"); // 創(chuàng)建消息摘要對象 MessageDigest md = MessageDigest.getInstance("MD5"); // 將鹽數(shù)據(jù)傳入消息摘要對象 md.update(salt); // 將口令的數(shù)據(jù)傳給消息摘要對象 md.update(password.getBytes("UTF-8")); // 生成輸入口令的消息摘要 byte[] digest = md.digest(); System.out.println("驗(yàn)證時的digest:"); for (byte b : digest) { System.out.print(b); } System.out.println(); System.out.println("驗(yàn)證時的digest end"); // 聲明一個保存數(shù)據(jù)庫中口令消息摘要的變量 byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH]; // 取得數(shù)據(jù)庫中口令的消息摘要 System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length); // 比較根據(jù)輸入口令生成的消息摘要和數(shù)據(jù)庫中消息摘要是否相同 if (Arrays.equals(digest, digestInDb)) { // 口令正確返回口令匹配消息 return true; } else { // 口令不正確返回口令不匹配消息 return false; } } /** * 獲得加密后的16進(jìn)制形式口令 * * @param password * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static String getEncryptedPwd(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { // 聲明加密后的口令數(shù)組變量 byte[] pwd = null; // 隨機(jī)數(shù)生成器 SecureRandom random = new SecureRandom(); // 聲明鹽數(shù)組變量 byte[] salt = new byte[SALT_LENGTH]; // 將隨機(jī)數(shù)放入鹽變量中 random.nextBytes(salt); // 聲明消息摘要對象 MessageDigest md = null; // 創(chuàng)建消息摘要 md = MessageDigest.getInstance("MD5"); // 將鹽數(shù)據(jù)傳入消息摘要對象 md.update(salt); // 將口令的數(shù)據(jù)傳給消息摘要對象 md.update(password.getBytes("UTF-8")); // 獲得消息摘要的字節(jié)數(shù)組 byte[] digest = md.digest(); System.out.println("加密后的digest:"); for (byte b : digest) { System.out.print(b); } System.out.println(); System.out.println("加密后的digest end"); // 因?yàn)橐诳诹畹淖止?jié)數(shù)組中存放鹽,所以加上鹽的字節(jié)長度 pwd = new byte[digest.length + SALT_LENGTH]; // 將鹽的字節(jié)拷貝到生成的加密口令字節(jié)數(shù)組的前12個字節(jié),以便在驗(yàn)證口令時取出鹽 System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH); // 將消息摘要拷貝到加密口令字節(jié)數(shù)組從第13個字節(jié)開始的字節(jié) System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length); System.out.println("加密后的pwd:"); for (byte b : pwd) { System.out.print(b); } System.out.println(); System.out.println("加密后的pwd end"); // 將字節(jié)數(shù)組格式加密后的口令轉(zhuǎn)化為16進(jìn)制字符串格式的口令 return byteToHexString(pwd); } public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException { // String str = // "E2935969488CA8E105B56CE2652121DE01D662DB848FEE2FF623E5E1"; // byte[] strBytes = hexStringToByte(str); // System.out.println("str hexStringToByte:"); // System.out.println("str:" + str); // for (int i = 0; i < strBytes.length; i++) { // System.out.print(strBytes[i]); // } // System.out.println(); // System.out.println("str hexStringToByte end"); // // System.out.println("還原后:" + byteToHexString(strBytes)); String pwd = "test123"; String pwddb = "AF80ECFD317BFD555D0D1DAEA4E45C45E40F446154D1F31FC89F0EA5"; System.out.println("加密后的密碼:" + getEncryptedPwd(pwd)); System.out.println(validPassword(pwd, pwddb)); } }
|
|