java md5加密 index页面代码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java md5加密 index页面代码相关的知识,希望对你有一定的参考价值。
类似这个。点击加密后,会出现一串密文的。
/**
* 将指定byte数组转换成16进制字符串
* @param b
* @return
*/
public static String byteToHexString(byte[] b)
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < b.length; i++)
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1)
hex = '0' + hex;
hexString.append(hex.toUpperCase());
return hexString.toString();
/**
* 获得加密后的16进制形式口令
* @param password
* @return
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
public static String getEncryptedPwd(String password)
throws NoSuchAlgorithmException, UnsupportedEncodingException
//声明加密后的口令数组变量
byte[] pwd = null;
//随机数生成器
SecureRandom random = new SecureRandom();
//声明盐数组变量
byte[] salt = new byte[SALT_LENGTH];
//将随机数放入盐变量中
random.nextBytes(salt);
//声明消息摘要对象
MessageDigest md = null;
//创建消息摘要
md = MessageDigest.getInstance("MD5");
//将盐数据传入消息摘要对象
md.update(salt);
//将口令的数据传给消息摘要对象
md.update(password.getBytes("UTF-8"));
//获得消息摘要的字节数组
byte[] digest = md.digest();
//因为要在口令的字节数组中存放盐,所以加上盐的字节长度
pwd = new byte[digest.length + SALT_LENGTH];
//将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐
System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);
//将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节
System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);
//将字节数组格式加密后的口令转化为16进制字符串格式的口令
return byteToHexString(pwd);
public static void main(String[] args) //测试方法
try
System.out.println(getEncryptedPwd("123456"));
catch (NoSuchAlgorithmException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (UnsupportedEncodingException e)
// TODO Auto-generated catch block
e.printStackTrace();
在jsp页面中可以调用getEncryptedPwd 方法
参考技术A <script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="js/md5.js" type="text/javascript">
</script>
</head>
<body>
输入:
<input type="text" id="user" name="user">
<br />
<button id="but">
加密
</button>
<br />
输出:
<input type="text" id="pwd" name="pwd">
</body>
<script type="text/javascript">
$("#but").click(function()
var u = MD5($("#user").val());
alert(u);
var a = document.getElementById("pwd");
a.setAttribute("value", u);
)
</script>
用户登录模块进行必要的安全处理(MD5加密加盐和传输过程加密)
1、首先简谈一下常规Web登录模块的开发(只为了实现简单的登录功能,未对数据库字段进行加密处理以及传输过程中进行加密处理)
非安全性登录模块开发
使用JSP+MYSQL
数据库表如下所示:
先用jsp页面创建login.jsp和index.jsp页面(为了方便讲解,直接使用jsp页面传值及校验)具体代码如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录界面</title> </head> <body> <form action="index.jsp" method="post"> 账 号:<input type="text" name="username"/><br/> 密 码:<input type="password" name="password"><br/><br/> <input type="submit" value="提交"><br/> </form> </body> </html>
<%@page import="java.sql.ResultSet"%> <%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.Connection"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>首页</title> </head> <body> <% //获取mysql连接对象 String driverClass="com.mysql.jdbc.Driver"; String user="root"; String psw="zwkkwz"; String url="jdbc:mysql://localhost:3306/mytest"; Class.forName(driverClass); Connection conn=DriverManager.getConnection(url,user,psw); //获取login.jsp传过来的username和password String username=request.getParameter("username"); String password=request.getParameter("password"); String sql="select * from login where username=?"; PreparedStatement stmt=conn.prepareStatement(sql); stmt.setString(1, username); ResultSet rs=stmt.executeQuery(); %> <% if(rs.next()){ String p=rs.getString("password"); if(password.equals(p)){ out.println("用户"+username+"登录成功"); }else{ out.println("用户"+username+"登录失败"); } }else{ out.println("用户"+username+"不存在"); } %> </body> </html>
通过上面两个jsp页面进行实现登录页面的,可以实现校验功能。但存在的安全隐患问题太多
- 数据库以明文的形式进行存储
- 数据传输的过程中未对数据进行加密处理(可以使用WireShark等抓包工具获取post传递的明文信息
2、接下来针对以上两个问题进行分析和解决:
安全加固1:对数据库表的password字段进行摘要处理(在MYSQL中对数据摘要处理,sql语句如下)
//使用SHA进行摘要处理 UPDATE loginset password = SHA(password) //使用MD5进行摘要处理 UPDATE userinfo set password = MD5(password)
原来明文123456 经过是用MD5加密后是e10adc3949ba59abbe56e057f20f883e
但是这样子还是不安全,进入http://www.cmd5.com/ 输入加密后的密文进行解密后可以得到明文密码
- 比如数据库有多个密码的明文是123456,通过MD5加密生成的密文是一模一样的,这样别人解密后就可以获取到其他一样的密码
- 针对上述问题,我们会进行加盐处理。即在用户注册时随机生成一个规定长度的字段,然后和用户密码相结合,在进行MD5加密,等会再讨论这个问题。
当对数据库的明文密码进行MD5加密后,我们再来改造一下jsp页面的处理逻辑,对用户输入的密码也进行MD5处理后再校验
- 写一个工具类DigestUtil,由这个工具类来帮助我们生成用户输入的password对应的MD5
- 写一个工具类BytesToString,将字节数组转化为字符串
- 具体代码分别如下,具体过程请读者自己分析代码
package util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class DigestUtil { public static String getMD5(byte[] data) throws NoSuchAlgorithmException{ MessageDigest md = MessageDigest.getInstance("MD5"); md.update(data); byte[] resultBytes = md.digest(); String resultString = BytesToString.fromBytesToString(resultBytes); return resultString; } public static String getSHA1(byte[] data) throws NoSuchAlgorithmException{ MessageDigest md = MessageDigest.getInstance("SHA1"); md.update(data); byte[] resultBytes = md.digest(); String resultString = BytesToString.fromBytesToString(resultBytes); return resultString; } }
package util; public class BytesToString { public static String fromBytesToString(byte[] resultBytes) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < resultBytes.length; i++) { if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) { builder.append("0").append( Integer.toHexString(0xFF & resultBytes[i])); } else { builder.append(Integer.toHexString(0xFF & resultBytes[i])); } } return builder.toString(); } }
改造后的index.jsp代码,如下:
<%@page import="util.DigestUtil"%> <%@page import="java.sql.ResultSet"%> <%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.Connection"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>首页</title> </head> <body> <% //获取mysql连接对象 String driverClass="com.mysql.jdbc.Driver"; String user="root"; String psw="zwkkwz"; String url="jdbc:mysql://localhost:3306/mytest"; Class.forName(driverClass); Connection conn=DriverManager.getConnection(url,user,psw); //获取login.jsp传过来的username和password String username=request.getParameter("username"); String password=request.getParameter("password"); String sql="select * from login where username=?"; PreparedStatement stmt=conn.prepareStatement(sql); stmt.setString(1, username); ResultSet rs=stmt.executeQuery(); %> <% if(rs.next()){ String p=rs.getString("password"); //简单的明文校验代码 /* if(password.equals(p)){ out.println("用户"+username+"登录成功"); }else{ out.println("用户"+username+"登录失败"); } }else{ out.println("用户"+username+"不存在"); } */ //sql使用MD5加密后的密文和用户输入的password校验代码 if(p.equals(DigestUtil.getMD5(password.getBytes()))) //getMD5(byte[] data)方法是将原始的数据转换成加密后的密文 { out.println("数据库password字段"+p); out.println("用户输入的password"+password); out.println("经过处理后的password"+DigestUtil.getMD5(password.getBytes())); out.println("用户"+username+"登录成功"); }else{ out.println("用户"+username+"登录失败"); } }else{ out.println("用户"+username+"不存在"); } %> </body> </html>
通过以上步骤,我们只对数据库的password明文字段进行了简单的MD5加密,有以下缺点:
- 容易根据密文位数推测算法,从而使用工具破解
- 真实密码相同,加密过的密码也相同
接下来我们介绍一下对其进行加盐处理:
3、加盐处理,以此来增强系统的复杂度,再通过摘要处理,就能得到隐蔽性更强的摘要值
- 将表中的salt字段随意输入abccba,然后和原来的明文密码123456结合,再进行SHA1加密
- 多建一对数据,将表中的salt字段输入cbaabc,然后和原来的明文密码123456结合,再进行SHA1加密
所谓的salt字段就是一个随机的字段,具体随机算法就不讨论了,每当用户注册账户时,后台就给它随机生成一个不同的字段
然后根据password和salt字段结合进行摘要处理,存在数据库表中的password字段,这样一来,原来明文都是123456生成的密文就不一样了
操作如下:
得到加密后密文是(原来密码都是123456):
接下来改造index.jsp的处理逻辑,对于用户输入的密码进行SHA1处理后的工具类在上面的DigestUtil方法中有列举出
index.jsp代码如下:
<%@page import="util.DigestUtil"%> <%@page import="java.sql.ResultSet"%> <%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.Connection"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>首页</title> </head> <body> <% //获取mysql连接对象 String driverClass="com.mysql.jdbc.Driver"; String user="root"; String psw="zwkkwz"; String url="jdbc:mysql://localhost:3306/mytest"; Class.forName(driverClass); Connection conn=DriverManager.getConnection(url,user,psw); //获取login.jsp传过来的username和password String username=request.getParameter("username"); String password=request.getParameter("password"); String sql="select * from login where username=?"; PreparedStatement stmt=conn.prepareStatement(sql); stmt.setString(1, username); ResultSet rs=stmt.executeQuery(); %> <% if(rs.next()){ String p=rs.getString("password"); //sql使用SHA1进行加盐加密后的密文和用户输入的password校验代码 //我们需要获取到用户输入的密码和对应的salt String salt=rs.getString("salt"); if(p.equals(DigestUtil.getSHA1((password+salt).getBytes()))){ out.println("数据库password字段"+p); out.println("用户输入的password"+password); out.println("经过处理后的password"+DigestUtil.getSHA1((password+salt).getBytes())); out.println("用户"+username+"登录成功"); }else{ out.println("用户"+username+"登录失败"); } }else{ out.println("用户"+username+"不存在"); } %> <% rs.close(); stmt.close(); conn.close(); %> </body> </html>
以上的步骤我们只是对sql进行了加密操作。
为了防止用户输入密码在传输的过程中被抓包工具获取,我们还要在密码传输的过程中进行加密,这样可以使得获取到的也是密文。
使用MD5.js对表单加密(可以百度搜索MD5.js下载)
传输加密:在浏览器端发送出数据之前就要对数据进行加密处理。
在jsp引入MD5.js;给input标签指定一个id,然后在提交的时候给定一个方法onclick,来对用户输入的密码进行加密,具体的login.jsp如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登录界面</title> <script type="text/javascript" src="md5.js"></script> </head> <body> <form action="index.jsp" method="post"> 账 号:<input type="text" name="username"/><br/> 密 码:<input type="password" name="password" id="password"><br/><br/> <input type="submit" value="提交" onclick="toMd5()"><br/> </form> </body> <script type="text/javascript"> function toMd5(){ var passwordNode=document.getElementById("password"); //加密前 alert(passwordNode.value); var hash=hex_md5(passwordNode.value); passwordNode.value=hash; //加密后 alert(passwordNode.value); } </script> </html>
以上是关于java md5加密 index页面代码的主要内容,如果未能解决你的问题,请参考以下文章
.net(md5)加密汉字的结果与java(md5)加密汉字的结果不一样。。。