1. 程式人生 > >之前發了一個登入表的設計,這裡是設計實現的程式碼:網站登入設計

之前發了一個登入表的設計,這裡是設計實現的程式碼:網站登入設計

簡單的使用者表設計如上圖:

程式碼如下所示: 隨機加密演算法6個:

package com.auth.sp.common.utils;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import sun.misc.BASE64Encoder;
import java.security.Key;
import java.security.MessageDigest;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
 * 作者: 薛俊鵬
 * 時間:2018/10/15 on  17:12 .
 * 描述:演算法中心
 * 內容:這裡記錄描述了N種需要金鑰的演算法
 * 每種演算法都會有一個特定的標識,根據標識鎖定演算法,最後在由MD5加密一次,加密的結果都保留大寫
 * 狀態: 編寫/修改
 */
public class AlgorithmCenter {
    /**金鑰演算法**/
    public static final String KEY_ALGORITHM = "AES";
    /**加解密演算法/工作模式/填充方式**/
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    /**
     * 加密資料 ral=1
     * @param data 待加密資料
     * @param key  金鑰 16位
     * @return 加密後的資料
     * */
    public static String AESencrypt1(String data, String key) throws Exception {
        Key k = new SecretKeySpec(key.getBytes("UTF-8"), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //例項化Cipher物件,它用於完成實際的加密操作
        cipher.init(Cipher.ENCRYPT_MODE, k); //初始化Cipher物件,設定為加密模式
        return Base64.encode(cipher.doFinal(data.getBytes("UTF-8"))); //執行加密操作。加密後的結果用Base64編碼進行傳輸
    }

    /**                                         ral = 1  end                     **/

    /**
     * 加密  ral=2
     * @param content
     *            需要加密的內容
     * @return
     */
    public static String AESencrypt2(String content,String key) {
        try {
            Cipher cipher = Cipher.getInstance("AES");// 建立密碼器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, genKey(key));// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return parseByte2HexStr(result); // 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * @mock 根據金鑰獲得 SecretKeySpec
     * @param strKey 加密解密金鑰
     * @return
     */
    private  static SecretKeySpec genKey(String strKey){
        byte[] enCodeFormat = {0};
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"  );
            secureRandom.setSeed(strKey.getBytes());
            kgen.init(128, secureRandom);
            SecretKey secretKey = kgen.generateKey();
            enCodeFormat = secretKey.getEncoded();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return new SecretKeySpec(enCodeFormat, "AES");
    }
    /**
     * 將二進位制轉換成16進位制
     * @param buf
     * @return
     */
    private static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**                                         ral = 2  end                     **/


    /**
     * MD5加密 生成32位md5碼
     */
    public static String AESencrypt3(String inStr,String key){
        MessageDigest md5 = null;
        try{
            md5 = MessageDigest.getInstance("MD5");
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
        char[] charArray = inStr.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++){
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16)
                hexValue.append("0");
            hexValue.append(Integer.toHexString(val));
        }
        return (hexValue.toString()+key).toUpperCase();
    }


    /**                                         ral = 3  end                     **/


    /**
     * base64加密 生成32位md5碼
     */
    public static String AESencrypt4(String content,String key){
        byte[] bt = content.getBytes();
        String str = (new BASE64Encoder()).encodeBuffer(bt);
        return (str.trim()+key).toUpperCase();
    }



    /**                                         ral = 4  end                     **/
    /**
     * Takes the raw bytes from the digest and formats them correct.
     *
     * @param bytes the raw bytes from the digest.
     * @return the formatted bytes.
     */
    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文轉換成十六進位制的字串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString().toUpperCase();
    }

    public static String AESencrypt5(String content,String key) {
        if (content == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(content.getBytes());
            return (getFormattedText(messageDigest.digest())+key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**                                         ral = 5  end                     **/



/**
   * 利用java原生的摘要實現SHA256加密
   * @param str 加密後的報文
   * @return
   */
    public static String AESencrypt6(String content,String key){
        MessageDigest messageDigest;
        String encodeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(content.getBytes("UTF-8"));
            encodeStr = byte2Hex(messageDigest.digest());
            } catch (Exception e) {
            e.printStackTrace();
            }
        return (encodeStr+key).toUpperCase();
       }

/**
   * 將byte轉為16進位制
   * @param bytes
   * @return
   */
    private static String byte2Hex(byte[] bytes){
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i=0;i<bytes.length;i++){
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length()==1){
                //1得到一位的進行補0操作
                stringBuffer.append("0");
                }
            stringBuffer.append(temp);
            }
        return stringBuffer.toString();
        }

    /**                                         ral = 6  end                     **/


        /*資料加密開始*/
    public static String GetAES(String value,int rand) throws  Exception{
        /*返回資料:加密資料+#+金鑰*/
        String key_vue = "";
        /*金鑰*/
        String km = "";
        GetKey key = new GetKey();
        switch (rand){
            case 1:
                km = key.KeyValue16();
                key_vue = ToMD5.MD5(AESencrypt1(value,km))+"#"+km;
                break;
            case 2:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5(AESencrypt2(value,km))+"#"+km;
                break;
            case 3:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5(AESencrypt3(value,km))+"#"+km;
                break;
            case 4:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5(AESencrypt4(value,km))+"#"+km;
                break;
            case 5:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5(AESencrypt5(value,km))+"#"+km;
                break;
            case 6:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5(AESencrypt6(value,km))+"#"+km;
                break;
            default:
                km = key.KeyValue32();
                key_vue = ToMD5.MD5("JIAMISHUJUCUOWU")+"#"+km;
                break;
        }
        return key_vue;
    }

    /*資料加密開始,加密資料,演算法,金鑰*/
    public static String GetAESEnd(String value,int rand,String km) throws  Exception{
        /*返回資料:加密資料*/
        String key_vue = "";
        switch (rand){
            case 1:
                key_vue = ToMD5.MD5(AESencrypt1(value,km));
                break;
            case 2:
                key_vue = ToMD5.MD5(AESencrypt2(value,km));
                break;
            case 3:
                key_vue = ToMD5.MD5(AESencrypt3(value,km));
                break;
            case 4:
                key_vue = ToMD5.MD5(AESencrypt4(value,km));
                break;
            case 5:
                key_vue = ToMD5.MD5(AESencrypt5(value,km));
            case 6:
                key_vue = ToMD5.MD5(AESencrypt6(value,km));
                break;
            default:
                key_vue = ToMD5.MD5("JIAMISHUJUCUOWU");
                break;
        }
        return key_vue;
    }



}

轉MD5:

package com.auth.sp.common.utils;

import java.security.MessageDigest;

/**
 * 作者: 薛俊鵬
 * 時間:2018/10/15 on  17:19 .
 * 描述:MD5演算法
 * 內容:
 * 狀態: 編寫/修改
 */
public class ToMD5 {

    public static String MD5(String key) {
        char hexDigits[] = {
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
        };
        try {
            byte[] btInput = key.getBytes();
            // 獲得MD5摘要演算法的 MessageDigest 物件
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的位元組更新摘要
            mdInst.update(btInput);
            // 獲得密文
            byte[] md = mdInst.digest();
            // 把密文轉換成十六進位制的字串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

}

登入方法:

package com.auth.sp.common.controller;
import com.auth.sp.common.aspect.ClearData;
import com.auth.sp.common.entity.LoginSystyem;
import com.auth.sp.common.entity.PwdKey;
import com.auth.sp.common.entity.SysKey;
import com.auth.sp.common.entity.SysUser;
import com.auth.sp.common.service.SysKeyService;
import com.auth.sp.common.service.SysUserService;
import com.auth.sp.common.shiro.ErrorReason;
import com.auth.sp.common.shiro.Token;
import com.auth.sp.common.utils.IPUtils;
import com.auth.sp.common.utils.Ognl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * 作者: 薛俊鵬
 * 時間:2018/10/12 on  17:55 .
 * 描述:登陸方法及控制 資料的攔截在許可權機中處理 所有不合法的請求重置到登陸頁面
 * 內容:
 * 狀態: 編寫/修改
 */
@RestController
public class LoginController {
    Log log = LogFactory.getLog(LoginController.class);
    @Autowired
    private SysUserService userService;
    @Autowired
    private SysKeyService keyService;

    /**登陸測試**/
    @RequestMapping(value = "log_in",method = RequestMethod.GET)
    public String Login(){
        List<SysUser> list = userService.SelectUser();
        SysUser user = new SysUser();
        for (int i = 0; i < list.size(); i++) {
            user = list.get(i);
            System.out.println("賬戶:"+user.getAccount());
        }
        return "OK-Account";
    }

    /**登入進入系統 全部返回json 資料**/
    @RequestMapping(value = "loginUser",method = RequestMethod.POST)
    public String LoginUser(@ModelAttribute LoginSystyem user, ModelMap model, HttpServletRequest request, HttpServletResponse response)
    throws Exception{
        /**使用者資訊判斷**/
        if(Ognl.isEmpty(user) || Ognl.isEmpty(user.getAccount()) || Ognl.isEmpty(user.getPwd())){
            /**清空物件**/
            user = null;
            /**清空快取資料**/
            response = ClearData.Clear(request,response);
            return ErrorReason.getErrorInfo(1).getErrorInfo();/*賬戶資訊不能為空,請重新輸入!*/
        }else{
            /**判斷賬戶資訊的準確性**/
            SysUser u = userService.selectByAccount(user.getAccount());
            /**使用者不存在**/
            if(Ognl.isEmpty(u)){
                /**清空物件**/
                user = null;
                u = null;
                /**清空快取資料**/
                response = ClearData.Clear(request,response);
                return ErrorReason.getErrorInfo(2).getErrorInfo();/*該賬戶資訊不存在!*/
            }else{
                /**存在使用者 記錄登入IP**/
                u.setLogin_ip(IPUtils.getLocalIP());
                userService.updateByPrimaryKeySelective(u);
                /**根據使用者id查詢使用者的金鑰資訊**/
                SysKey sysKey = keyService.selectByUserId(u.getId());
                if(Ognl.isEmpty(sysKey)){
                    log.info("sysKey資料異常,請及時處理!");
                    /**清空物件**/
                    user = null;
                    sysKey = null;
                    /**清空快取資料**/
                    response = ClearData.Clear(request,response);
                    return ErrorReason.getErrorInfo(3).getErrorInfo();/*賬戶異常,請及時聯絡管理員!*/
                }else{
                    /**密碼輸入超過5次,踢出系統,清除登陸痕跡**/
                    if(u.getError_time()>=5){
                        /**清空物件**/
                        user = null;
                        user = null;
                        sysKey = null;
                        /**清空快取資料**/
                        response = ClearData.Clear(request,response);
                        return "密碼多次輸入錯誤,"+ErrorReason.getErrorInfo(6).getErrorInfo();
                    }else {
                        /**資料置換,防止SQL攻擊**/
                        PwdKey pwdKey = new PwdKey();
                        pwdKey.setKey(sysKey.getUser_key());
                        pwdKey.setValue(sysKey.getPwd());
                        pwdKey.setAccount(user.getPwd());
                        pwdKey.setNum(u.getAlg());
                        boolean isOk = SysUserController.IsPassPwd(pwdKey);
                        /**密碼一致確認身份資訊,密碼不一致,踢出系統**/
                        if (!isOk) {
                            log.info(user.getAccount() + "密碼輸入錯誤!");
                            /**密碼錯誤更新錯誤密碼次數**/
                            u.setError_time(u.getError_time() + 1);
                            /**錯誤次數達到上限,凍結使用者**/
                            if (u.getError_time() >= 5) {
                                u.setFreeze(0);
                                u.setReason("密碼輸入錯誤次數超過5次");
                            }
                            userService.updateByPrimaryKeySelective(u);
                            /**清空物件**/
                            user = null;
                            pwdKey = null;
                            user = null;
                            sysKey = null;
                            /**清空快取資料**/
                            response = ClearData.Clear(request, response);
                            return ErrorReason.getErrorInfo(4).getErrorInfo();/*密碼輸入錯誤*/
                        } else {
                            if(u.getFreeze()==0){
                                /**清空物件**/
                                user =  null;
                                u = null;
                                pwdKey = null;
                                sysKey = null;
                                /**清空快取資料**/
                                response = ClearData.Clear(request, response);
                                return ErrorReason.getErrorInfo(6).getErrorInfo()+"請聯絡管理員處理!";
                            }else {
                                /**更新使用者資訊**/
                                u.setError_time(0);
                                u.setReason("");
                                userService.updateByPrimaryKeySelective(u);
                                log.info(u.getAccount() + "歡迎進入系統...");
                                /**進入系統之後,全稱使用加密的身份驗證,驗證失敗,或者超時,踢出系統**/
//                                request.getSession().setAttribute("token", Token.EncryMacSHA(u.getAccount()));
                                request.getSession().setAttribute("uname1",u.getAccount());
                                HttpSession session = request.getSession();
                                request.getSession().setAttribute("u",u);
                                session.setAttribute("token",Token.EncryMacSHA(u.getAccount()));
                                session.setAttribute("uname",u.getAccount());
                                pwdKey = null;
                                user = null;
                                sysKey = null;
                                String result = ErrorReason.getErrorInfo(5).getErrorCode();/*授權通過*/
                                return result;
                            }
                        }
                    }
                }
            }
        }
    }


}

資料清除:

package com.auth.sp.common.aspect;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

/**
 * 作者: 薛俊鵬
 * 時間:2018/10/22 on  10:53 .
 * 描述:主要用於資料的清空和初始化處理
 * 內容:
 * 狀態: 編寫/修改
 */
public class ClearData {

    /**session的初始化和清空操作**/
    public static void initSession(HttpServletRequest request){
        /**獲取所有session 列舉**/
        Enumeration em = request.getSession().getAttributeNames();
        while(em.hasMoreElements()){
            request.getSession().removeAttribute(em.nextElement().toString());
        }
    }

    /**清空cookie**/
    public static HttpServletResponse CleanCookies(HttpServletRequest request,HttpServletResponse response){
        /**獲取所有cookie資訊**/
        Cookie[] cookies=request.getCookies();
        for(Cookie cookie: cookies){
      /**使用完立即刪除**/
            cookie.setMaxAge(0);
      /**所有路徑下的cookie**/
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        return response;
    }

    public static HttpServletResponse Clear(HttpServletRequest request,HttpServletResponse response){
        /**清空session**/
        ClearData.initSession(request);
        request.getSession().invalidate();
        /**清空cookie**/
        response = ClearData.CleanCookies(request,response);
        return response;
    }

}