之前发了一个登录表的设计,这里是设计实现的代码:网站登录设计

简单的用户表设计如上图:

代码如下所示:
随机加密算法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;
    }

}


错误信息封装:

package com.auth.sp.common.shiro;

/**
 * 作者: 薛俊鹏
 * 时间:2018/10/25 on  11:42 .
 * 描述:错误定义
 * 内容:
 * 状态: 编写/修改
 */
public class ErrorBean {
    /**错误标识**/
    private int identification;
    /**错误代码**/
    private String errorCode;
    /**错误中文**/
    private String errorInfo;
    /**错误英文**/
    private String errorMsg;

//    get   set

    public int getIdentification() {
        return identification;
    }

    public void setIdentification(int identification) {
        this.identification = identification;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorInfo() {
        return errorInfo;
    }

    public void setErrorInfo(String errorInfo) {
        this.errorInfo = errorInfo;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}

 

 

错误信息配置:

package com.auth.sp.common.shiro;

/**
 * 作者: 薛俊鹏
 * 时间:2018/10/25 on  11:41 .
 * 描述:定义错误信息
 * 内容:
 * 状态: 编写/修改
 */
public class ErrorReason {

    public static ErrorBean getErrorInfo(int identification) {
        String code = "9999";/*错误代码*/
        String info = "未知错误";/*中文信息*/
        String errorMsg = "unknown error";/*英文解释*/
        switch (identification) {
            case 1:
                code = "N0001";
                info = "账户信息不能为空,请重新输入!";
                errorMsg = "Account information can not be empty. Please re-enter it!";
                break;
            case 2:
                code = "N0002";
                info = "该账户信息不存在!";
                errorMsg = "The account information does not exist!";
                break;
            case 3:
                code = "N0003";
                info = "账户异常,请及时联系管理员!";
                errorMsg = "Account exception, please contact the administrator in time!";
                break;
            case 4:
                code = "N0004";
                info = "密码输入错误,请重新输入!";
                errorMsg = "Password input error, please re input!";
                break;
            case 5:
                code = "N0005";
                info = "授权通过!";
                errorMsg = "Permit passage!";
                break;
            case 6:
                code = "N0006";
                info = "账户已被系统冻结!";
                errorMsg = "The account has been frozen!";
                break;
            default:
                code = "N9999";
                info = "未知异常,请联系管理员!";
                errorMsg = "Unknown exception, please contact the administrator!";
                break;
        }
        ErrorBean errorInfo = new ErrorBean();
        errorInfo.setErrorCode(code);
        errorInfo.setErrorInfo(info);
        errorInfo.setErrorMsg(errorMsg);
        return errorInfo;
    }

}
 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值