安全性对于项目非常的重要,特别是用户的数据安全。今天,我们将讨论一下如何在用户登录过程中保证密码的安全。
这是非对称算法下密码传输的流程图,在客户端用公钥进行加密,在服务器端用私钥进行解密,这样的好处是,即使用户密码在传输过程中被非法拦截了,拦截者没有私钥,也就没有办法对密码进行解密。这样就保证了数据安全。但是,这样并不能避免请求伪造。如果服务器端和客户端密钥一直不变,那么拦截者只需要拦截到客户端发送的密码,无需关心原始的用户密码是什么便能进行伪造登陆。解决这个问题的方法就是,每次登陆的时候,都要生成新的公钥和私钥。使每次加密后的密码都是变化的。这样就避免的请求伪造的问题。
我们用rsa算法来演示一下javaweb中如何进行密码安全传输:
客户端login.jsp,需要引入RSA.js
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="Utils.RSAUtils,java.util.*,java.security.interfaces.RSAPublicKey,java.security.interfaces.RSAPrivateKey"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%
HashMap<String, Object> map = RSAUtils.getKeys();
//生成公钥和私钥
RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
//私钥保存在session中,用于解密
session.setAttribute("privateKey", privateKey);
//公钥信息保存在页面,用于加密
String publicKeyExponent = publicKey.getPublicExponent().toString(16);
String publicKeyModulus = publicKey.getModulus().toString(16);
request.setAttribute("publicKeyExponent", publicKeyExponent);
request.setAttribute("publicKeyModulus", publicKeyModulus);
%>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="js/RSA.js"></script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
function login(){
RSAUtils.setMaxDigits(200);
var key = new RSAUtils.getKeyPair("${publicKeyExponent}", "", "${publicKeyModulus}");
var OrgPass=$("#pass").val();
var encrypedPwd = RSAUtils.encryptedString(key,OrgPass.split("").reverse().join(""));
$("#realPass").attr("value",encrypedPwd);
//$("form").submit();
}
</script>
</head>
服务器端
package Controller;
import java.io.IOException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import Utils.RSAUtils;
@WebServlet("/SecurityController")
public class SecurityController extends HttpServlet {
private static final long serialVersionUID = 1L;
public SecurityController() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 1.获取密码
String passWordSec = request.getParameter("realPass");
System.out.println(passWordSec);
// 2.获取该session对应的私钥
RSAPrivateKey privateKey = (RSAPrivateKey) request.getSession().getAttribute("privateKey");
// 3.进行解密
if (privateKey != null) {
long time1 = System.currentTimeMillis();
passWordSec = RSAUtils.decryptByPrivateKey(passWordSec, privateKey);
request.getSession().removeAttribute("privateKey");
}
System.out.println(passWordSec);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}