MD5Util (MD5加密摘要演算法)。

suyu_yuan發表於2016-07-06


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


public class MD5Util {


    //16進位制需要的字串資料
    private static final String HEX_NUMS_STR = "0123456789ABCDEF";


    //隨機字串位元組數長度
    private static final Integer BYTE_LENGTH = 18;


    /**
     * 將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();
    }
    
    public static String getMD5to16(String plainText) {
   
    String result = "";
   
    try {
            //生成實現指定摘要演算法的 MessageDigest 物件。
            MessageDigest md = MessageDigest.getInstance("MD5");  
            //使用指定的位元組陣列更新摘要。
            md.update(plainText.getBytes());
            //通過執行諸如填充之類的最終操作完成雜湊計算。
            byte[] b = md.digest();
            //生成的md5換成16進位制字串
            result = byteToHexString(b);
            System.out.println("temp16位: " + result);
            
         } catch (Exception e) {
        e.printStackTrace();
         }
    return result;
    }


    /**
     * 獲得加密後的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[] randomByte = new byte[BYTE_LENGTH];
        // 將隨機數放入隨機陣列變數中
        random.nextBytes(randomByte);


        // 宣告訊息摘要物件
        MessageDigest md = null;
        // 建立訊息摘要
        md = MessageDigest.getInstance("MD5");
        // 將原資料傳入訊息摘要物件
        md.update(randomByte);
        // 將口令的資料傳給訊息摘要物件
        md.update(password.getBytes("UTF-8"));
        // 獲得訊息摘要的位元組陣列
        byte[] digest = md.digest();


        // 因為要在口令的位元組陣列中存放隨機陣列密文,所以加上隨機陣列的位元組長度
        pwd = new byte[digest.length + BYTE_LENGTH];
        // 將原的位元組拷貝到生成的加密口令位元組陣列的前相應該長度BYTE_LENGTH個位元組,以便在驗證口令時取出隨機陣列
        System.arraycopy(randomByte, 0, pwd, 0, BYTE_LENGTH);
        // 將訊息摘要拷貝到加密口令位元組陣列從第BYTE_LENGTH個位元組開始的位元組
        System.arraycopy(digest, 0, pwd, BYTE_LENGTH, digest.length);
        // 將位元組陣列格式加密後的口令轉化為16進位制字串格式的口令


        return byteToHexString(pwd);
    }


    /**
     * 驗證口令是否合法
     *
     * @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[] randomByte = new byte[BYTE_LENGTH];
        // 將隨機陣列從資料庫中儲存的口令位元組陣列中提取出來,按其長度
        System.arraycopy(pwdInDb, 0, randomByte, 0, BYTE_LENGTH);
        // 建立訊息摘要物件
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 將隨機陣列據傳入訊息摘要物件
        md.update(randomByte);
        // 將口令的資料傳給訊息摘要物件
        md.update(password.getBytes("UTF-8"));
        // 生成輸入口令的訊息摘要
        byte[] digest = md.digest();
        // 宣告一個儲存資料庫中口令訊息摘要的變數
        byte[] digestInDb = new byte[pwdInDb.length - BYTE_LENGTH];
        // 取得資料庫中口令的訊息摘要
        System.arraycopy(pwdInDb, BYTE_LENGTH, digestInDb, 0,digestInDb.length);
        // 比較根據輸入口令生成的訊息摘要和資料庫中訊息摘要是否相同
        if (Arrays.equals(digest, digestInDb)) {
            // 口令正確返回口令匹配訊息
            return true;
        } else {
            // 口令不正確返回口令不匹配訊息
            return false;
        }
    }
    
    public static void main(String[] args) {
   
    getMD5to16("asdfasdfa");
   
    }
}

相關文章