发表于: 2017-09-15 10:19:44
4 690
今天完成的事情:
md5算法为什么是不可逆的?
public class MD5Util {
public static String stringToMD5(String string){
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//计算md5函数
md.update(string.getBytes());
//digest()最后确定返回md5 hash值,返回值为8位zifuc,
// 因为md5 hash值是16位的hex值,实际上就是8位的字符
//BigInteger函数则将8位的字符串转换成16位的hex值,用字符串来表示:得到字符串形式的hash值
return new BigInteger(1,md.digest()).toString(16);
}
}
我用的这个md5算法就是将密码加密之后转换成一个32位的hash值
就这个32位的字符串我们可以想到它的组合肯定是有限多个的,而我们可以用来加密的原文必然是无限多的。很明显,无限对有限,那么可能相同的密文就指代了不同的原文,这基本就不可能破解了。
然而实际上我们并没有无限多个原文,所以密文在一定程度上可以保证一对一。
其实md5可以算作一种压缩技术,只是不可逆的压缩。比如我们的密码长度为100,md5在压缩过程中其实导致了原文的一部分丢失,这样出来的结果是无法破解的,因为就算知道了md算法也无法完美还原出原值,何况如果我们加密一个大文件的话。。。
之前我的密码是123456加盐也是随便加的,很容易就被破界网站破解了
现在我的密码是
从南边来了个喇嘛,手里提拉着五斤塔嘛,从北边来个哑吧,腰里别着个喇叭。提拉塔嘛的喇嘛要拿塔嘛换别喇叭哑巴的喇叭,别喇叭的哑巴不愿意拿喇叭换提拉塔嘛喇嘛的塔嘛,提拉塔嘛的喇嘛拿塔嘛打了别喇叭的哑巴一塔嘛,别喇叭的哑巴拿喇叭打了提拉塔嘛的喇嘛一喇叭。也不知提拉塔嘛的喇嘛拿塔嘛打坏了别喇叭哑巴的喇叭,也不知别喇叭的哑巴拿喇巴打坏了提拉塔嘛喇嘛的塔嘛。提拉塔嘛的喇嘛敦塔嘛,别喇叭的哑巴吹喇叭。
生成的md5是
24597d7db0830012c4efdbb2ffe6c773
解密一下看看
基本上是不会被破解的。可以看出md5加盐的目的其实就是把密码弄得很复杂就会难以破解,甚至不能破解。
md5碰撞
2004由我国科学家首先提出的,可以利用碰撞法来构造出一模一样的md5
然后现在还可以在网上找到md5碰撞器。。
就类似于指纹吧,现在也有伪造指纹的方法了,所以这种方法已经不那么安全了。
关于cookie的存放位置
其实没有任何设置的cookie的有效时间为2分钟,它是存放在内存里的,当会话结束时会被自动删除
如果设置了cookie过期时间,那么才会存放到本地的硬盘里
现在我设置了cookie过期时间然后登陆,在chrome里可以看到
有效期7天,很明显是放在硬盘中的。
现在我退出登陆,把过期时间删了,然后再次启动项目,登陆
可以看到
这个是新的token,很明显是放在内存中的,在会话结束,也就是关闭浏览器,就消失了。
response和request,这个我会用但是一直没整理
这俩难兄难弟是一起存在和一起消亡的,也就是生命周期在一次请求中..
从字面意思就能看出来,响应和请求。
直接来看response的相关方法吧
addCookie(Cookie cookie)就是向response中添加一个cookie,然后服务器会把这个cookie交给客户端
addHeader(String name, String value)向客户端添加一个字符串值响应头信息,比如重定向的location
sendRedirect(String name)请求重定向,功能和location一样
setHeader(String name, String value)和上边那个一样,只不过是修改响应头信息
setStatus(int value)设置响应码
getOutputStream()可以拿到一个字节流,然后向response容器中写入字节数据,客户端可以向response容器拿取数据
getWriter()可以拿到一个字符流,巴拉巴拉。。
setContentType()可以直接设置响应头content-type的内容
这些方法就涉及到了很多以后任务能用到的知识,只讲目前的吧
请求重定向
最好不要用,因为这会再发送一次请求,也就是两次请求,也就会出现两个request,response,同时url会发生改变
响应码302,代表暂时性转移,这种方式很容易出现问题,经常被用于url劫持。就是比如网址A设定了一个重定向到网址B,但是在浏览器抓取的时候可能只显示内容而不切换url,就变成了任然是A网站但是内容是B网站的。
响应码301,永久重定向,这个就好很多,
然后而我们使用这个
httpServletResponse.sendRedirect("/u/job");
它的本质其实是
httpServletResponse.setStatus(302);
httpServletResponse.setHeader("location","/u/job");
然后今天优化代码的时候又发现一个有意思的问题
应该是之前一直没注意,在没有cookie的时候进入这个/u/job正常情况应该由拦截器直接跳转到/login,但是
它竟然进入了我写的有cookie的代码里,然后再出去跑去重定向。。
报错:
你输入的数据(密文数据)长度必须是 8 的整数倍。
很明显此时并没有cookie,也就没有token,也就没有密文
突然我想到,是不是localhost还有别的cookie存在
妈的果然,这个是服务器session发给浏览器的sessionid,它也存在cookie里,有意思了
我来看看到底是不是这个东西在搞鬼
System.out.println("调用拦截器");
Cookie[] cookie = httpServletRequest.getCookies();
if(cookie != null) {
System.out.println("有cookie才进来,我日你哥!");
for (int i = 0; i < cookie.length; i++) {
System.out.println("遍历");
if (cookie[i].getName().equals("JSESSIONID"))
System.out.println("cookie: " + cookie[i]);
然后
果然就是它!所以我这永远都不可能没有cookie的,永远不能。
可能有人会觉得我把它删了不就行了么?
然后,每次重定向都算是一次请求,只要有请求就会创建session,你懂的。所以我这个拦截方法应该要改一下了。
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("调用拦截器");
Cookie[] cookie = httpServletRequest.getCookies();
if(cookie != null) {
System.out.println("有cookie才进来,我日你哥!");
for (int i = 0; i < cookie.length; i++) {
System.out.println("遍历");
if (cookie[i].getName().equals("token")) {
try {
String token = cookie[i].getValue();
System.out.println("token"+token);
byte[] tk = TypeUtil.hexStringToByte(token);
byte[] tk1 = DES.decrypt(tk, "12345678");
String tk2 = new String(tk1);
System.out.println("cookie中的token进行解密");
String[] sArr=tk2.split("=");
String id=sArr[0];
String date=sArr[1];
Long time=Long.parseLong(date);
System.out.println("time="+time);
if (userService.select(Integer.parseInt(id)) != null) {
return true;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
String contextPath = httpServletRequest.getContextPath();
String uri = contextPath + "/login";
System.out.println("重定向路径:" + uri);
httpServletResponse.sendRedirect(uri);
return false;
}
然后我感觉做完了就欢欢喜喜地提交任务了。。。结果还是被师兄问住了,学艺不精啊!
拦截器究竟拦截了什么?
首先需要知道的一点,拦截器是aop的另一种叫法,知道这个就简单很多了(我就一直不知道)
这次我知道它是面向切面编程了,好的,在web设置里添加了拦截/u/*的url,当我们访问/u网址的时候,拦截器生效
看我上面那个拦截器代码,我在return false前添加了重定向,意思是如果没发现token的话,就重定向到/login,很明显那个返回值是没用的,我现在注释掉重定向看看
// String contextPath = httpServletRequest.getContextPath();
// String uri = contextPath + "/login";
// System.out.println("重定向路径:" + uri);
// httpServletResponse.sendRedirect(uri);
return false;
哇,一片空白,啥也没有。进到了/u/job但是被拦截住了,所以不会跳转成功,也不会退到前一个页面,就此卡住。
前边的方法,如果return true了的话,就跳出拦截器进入应该进去的/u/job。
还有一点
之前一直看到一个叫做action的东西一直不知道是什么,今天查了一下发现是Struts框架里的,类似于springmvc中的controller。spring框架的拦截是方法级别的拦截,Struts的拦截则是类级别的。总体来说spring要更好用一些,就因为这个ioc功能,别的方面有时间在了解吧。
明天计划的事情:
任务6,先看看需求
遇到的问题:
大部分都解决了,需要优化一下代码,md5的算法在不耽误正常进度的情况下看看吧
收获:
md5,cookie,拦截器,一些小知识的积累
评论