发表于: 2017-11-13 23:02:39

2 904


今日完成:

                 1)MD5加盐算法: 

//普通MD5算法

public static String MD5(String input){

byte[] bytes=input.getBytes();

MessageDigest messageDigest= null;
try {
messageDigest = MessageDigest.getInstance("MD5");
byte[]output=messageDigest.digest(bytes);

String value=toHex(output);
return value;

   } catch (NoSuchAlgorithmException e) {
e.printStackTrace();
   }
return null;
}
//MD5加盐,获得盐值,并且将盐值放入MD5对应的字符串中产生干扰,减少破解的难度。
public static   String salt(String password){
Random random=new Random();
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append(random.nextInt(99999999)+"").append(random.nextInt(99999999)+"");
int length=stringBuilder.length();
for (int i=0;i<16-length;i++){
stringBuilder.append("0");
   }
String salt=stringBuilder.toString();
String value=MD5(password+salt);
char[] result=new char[48];
for (int i=0;i<48;i+=3){
result[i]=value.charAt(i/3*2);
result[i+1]=salt.charAt(i/3);
result[i+2]=value.charAt(i/3*2+1);
   }
return new String(result);
}
//验证
public  static  boolean voliate(String password,String md5){
StringBuilder stringBuilder1=new StringBuilder();
StringBuilder stringBuilder2=new StringBuilder();
for(int i=0;i<md5.length();i+=3){
stringBuilder1.append(md5.charAt(i));
stringBuilder2.append(md5.charAt(i+1));
stringBuilder1.append(md5.charAt(i+2));
   }
String value=stringBuilder1.toString();
String salt=stringBuilder2.toString();
String result=MD5(password+salt);
if (result.equals(value)){
return true;
   }
return  false;

}

//将数据转为16进制字符串

public static String toHex(byte[] bytes){
StringBuilder stringBuilder=new StringBuilder();
for (int i=0;i<bytes.length;i++){
Integer value=bytes[i]&0xff;
if (value<16){
stringBuilder.append("0");
       }
stringBuilder.append(Integer.toHexString(value));
   }
return stringBuilder.toString();
}

                            为什么使用MD5加盐?

                                  我理解的,作为MD5的升级版本,MD5数据如果被人截获的话,是会被解出来的(有专门的网站,直接可以破解MD5数据,十分简单);而且,就算不会被解出来,获得了一大批数据库中的MD5的密码,通过尝试也会找到相同的密码。这是非常不安全的。所以,作为MD5的升级版本,MD5加盐因为生成的字符串不是标砖的MD5 128码,所以不会担心被直接解出来;另外,因为加入了随机数,所以被尝试找到密码的可能性也大大降低。但是反过来说,如果别人拿到这个串,也知道相关的算法,那么这个数据也就没有安全性可言了。   综上,,,,安全不是绝对的,,,,网络安全是个很深奥的问题啊,,,

                      2)关于Token写入Cookie

                          首选,,在网上百度了好多关于Token的知识,Token是一个令牌,使用的方式也多种多样,所以,具体情况还得具体分析。

先看一下把Token放入Cookie的代码。在登陆对应的Controller                

//验证登录,签发Token
@RequestMapping(value = "/login",method = RequestMethod.POST)
public  String toLogin(User user, Model model, HttpServletRequest request, HttpServletResponse response){
if (user.getPassword()==null||user.getPassword().trim().equals("")){
return "redirect:/user/loginpage";
   }

User currentUser=userService.findUserByUsername(user.getUsername());

//密码我用的MD5加盐进行加密并且验证,如果验证通过,签发Token放入Cookie中

if (Md5Utils.voliate(user.getPassword(),currentUser.getPassword())){


//Token包含两部分,用户ID,当前时间.为了增加安全性,在验证的时候,添加了UA,这样即使别人得到了Token数据,也没办法验证成功

String token=currentUser.getId()+"="+System.currentTimeMillis();

String password="zhangqi123";
String UA=request.getHeader("User-Agent");
token= new String(DESUtils.encryption(token,password+UA));
Cookie cookie=new Cookie("token",token);

//设置过期时间

cookie.setMaxAge(60*60*24*7);

cookie.setPath("/");

response.addCookie(cookie);

//验证成功进入hello

return "redirect:/hello";

   }

//验证不成功的话回到登陆页面重新登陆

return "redirect:/user/loginpage";

}

                          接下来是拦截器对应的代码,拦截器拦截/hello页面,这个页面只有用户登录之后才可以访问。

public class LoginInterceptor implements HandlerInterceptor {
@Autowired
   private UserService userService;
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
Cookie[] cookies=httpServletRequest.getCookies();

if (cookies!=null){
for (int i=0;i<cookies.length;i++){
if (cookies[i].getName().equals("token")){
String value=cookies[i].getValue();
/*
                  * 加入客户端请求头,作为干扰信息
                  * */
                   String UA=httpServletRequest.getHeader("User-Agent");
String tokens=DESUtils.decrypt(value,"zhangqi123"+UA);

String id=tokens.substring(0,tokens.indexOf("="));

//根据得到的ID查询数据库,如果数据库中有相应的数据,表示已经登录。可以访问hello页面

if (id!=null&&!id.trim().equals("")){

User user=userService.findUserById(Integer.valueOf(id))
if (user!=null){
return  true;
}
}
break;
}
}
}
httpServletResponse.sendRedirect("/user/loginpage");
return false;
}

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}
}

                              总体思路,用户的密码放在数据库中的时候使用的是MD5加盐加密,当用户登录的时候,先进行验证,验证通过签发Token(用户id+当前时间组成),Token使用DES加密,加密的秘钥是自定义的密码+UA(客户端相关信息),这样可以增加安全度。



今日疑问:

       无。



明日任务:

            再整理一下,进入下一个任务~~~

                                 


返回列表 返回列表
评论

    分享到