1. 程式人生 > >加鹽加密的方式

加鹽加密的方式

   加鹽加密是一種對系統登入口令的加密方式,它實現的方式是將每一個口令同一個叫做”鹽“(salt)的n位隨機數相關聯。無論何時只


要口令改變,隨機數就改變。隨機數以未加密的方式存放在口令檔案中,這樣每個人都可以讀。不再只儲存加密過的口令,而是先將口令和


隨機數連線起來然後一同加密,加密後的結果放在口令檔案中。 

工具類的實現:

package com.sangame.core.utils;


import org.apache.commons.codec.binary.Hex;


import java.security.MessageDigest;


/**
 * 加鹽加密工具類
 */
public class EncryptedUtil {


    /**
     * 加鹽字串,長度必須為16位。
     */
    private final static String salt = "aaaaaaaaaaaaaa3a";


    /**
     * 生成含有加鹽的密碼
     */
    public static String generate(String password) {
        return generate(password, null);
    }


    /**
     * 生成含有加鹽的密碼
     */
    public static String generate(String password, String userName) {


        String salt = getSalt(userName);


        password = md5Hex(password + salt);
        char[] cs1 = password.toCharArray();
        char[] cs2 = salt.toCharArray();
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = cs1[i / 3 * 2];
            cs[i + 1] = cs2[i / 3];
            cs[i + 2] = cs1[i / 3 * 2 + 1];
        }
        return new String(cs).toUpperCase();
    }


    private static String getSalt(String salt){
        if(salt == null || salt.length() == 0){
            return EncryptedUtil.salt;
        }


        if(salt.length() <= 16 ){
            return getStringLen8(salt) + EncryptedUtil.salt.substring(7, 15);
        } else {
            return salt.substring(4, 12) + EncryptedUtil.salt.substring(2, 10);
        }
    }


    public static String getStringLen8(String salt){
        if(salt.length() == 8){
            return salt;
        }
        if(salt.length() > 8){
            return salt.substring(1, 9);
        } else {
            return getStringLen8(salt + salt);
        }
    }


    /**
     * 校驗密碼是否正確
     */
    public static boolean verify(String password, String md5) {
        char[] cs = md5.toLowerCase().toCharArray();
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = cs[i];
            cs1[i / 3 * 2 + 1] = cs[i + 2];
            cs2[i / 3] = cs[i + 1];
        }
        String salt = new String(cs2);
        return md5Hex(password + salt).equals(new String(cs1));
    }


    /**
     * 獲取十六進位制字串形式的MD5摘要
     */
    private static String md5Hex(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bs = md5.digest(src.getBytes());
            return new String(new Hex().encode(bs));
        } catch (Exception e) {
            return null;
        }
    }
}