Javascript端加密java服务端解密
通常我们会通过htts来保证传输安全,但如果我们不用https,如何通过javascript来保证浏览器端发送的参数进行加密,并且通过RSA算法来处理。
这里我们可以利用jquery的一个加密插件jcryption来处理,可以参考
http://jcryption.org/#examples
现在版本是3.0 但是没有java端的实现,下次有时间再研究。现在这个用的是1.1的版本
这个可以在
http://linkwithweb.googlecode.com/svn/trunk/Utilities/jCryptionTutorial获取
不过他的服务端有个缺陷我修改了。
接来大致介绍如下:
1.首先服务端有产生publicKey的servlet:
package com.gsh.oauth.auth.servlet;
import java.io.IOException;
import java.security.KeyPair;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
import com.gsh.oauth.auth.util.JCryptionUtil;
/**
*Servlet implementation class EncryptionServlet
*/
public class EncryptionServlet extendsHttpServlet {
privatestatic final long serialVersionUID = 1L;
/**
* Default constructor.
*/
publicEncryptionServlet() {
//TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#service(HttpServletRequestrequest, HttpServletResponse response)
*/
protectedvoid service(HttpServletRequest request,
HttpServletResponseresponse) throws ServletException, IOException {
intKEY_SIZE = 1024;
if(request.getParameter("generateKeypair") != null) {
JCryptionUtiljCryptionUtil = new JCryptionUtil();
KeyPairkeys = null;
//if(request.getSession().getAttribute("keys") == null) { //这里注释掉否则第二次请求会500
keys= jCryptionUtil.generateKeypair(KEY_SIZE);
request.getSession().setAttribute("keys",keys);
//}
StringBufferoutput = new StringBuffer();
Stringe = JCryptionUtil.getPublicKeyExponent(keys);
Stringn = JCryptionUtil.getPublicKeyModulus(keys);
Stringmd = String.valueOf(JCryptionUtil.getMaxDigits(KEY_SIZE));
output.append("{\"e\":\"");
output.append(e);
output.append("\",\"n\":\"");
output.append(n);
output.append("\",\"maxdigits\":\"");
output.append(md);
output.append("\"}");
output.toString();
response.getOutputStream().print(
output.toString().replaceAll("\r","").replaceAll("\n", "")
.trim());
}else {
response.getOutputStream().print(String.valueOf(false));
}
}
}
2.Client例子
<html>
<head>
<title>Login form</title>
</head>
<metahttp-equiv="Content-Type"
content="text/html; charset=utf-8">
<scriptsrc="../js/jquery-1.4.2.min.js"type="text/javascript"></script>
<scriptsrc="../js/jquery-ui-1.8.2.custom.min.js"
type="text/javascript"></script>
<scripttype="text/javascript"
src="../js/security/jquery.jcryption-1.1.min.js"></script>
<scripttype="text/javascript">
$(document).ready(function() {
var $statusText = $('<span id="status"></span>').hide();
$("#status_container").append($statusText);
$("#lf").jCryption({
getKeysURL:"/gsh/oauth/encryption?generateKeypair=true",
beforeEncryption: function(){
$statusText
.text("Test Code")
.show();
returntrue;
},
encryptionFinished: function(
encryptedString,
objectLength){
$statusText
.text(encryptedString);
returntrue;
}
});
});
</script>
<body>
<formid="lf"action="/gsh/oauth/authorization"
method="post">
<fieldset><legend>login</legend>
<div>
<div>client_id:<br>
<inputtype="text"size="45"name="client_id"value=""></div>
<div>redirect_uri:<br>
<inputtype="text"size="45"name="redirect_uri"value=""></div>
</div>
<div>loginid:<br>
<inputtype="text"size="45"name="loginid"value=""></div>
</div>
<div>password:<br>
<inputtype="password"size="45"name="password"value=""></div>
</div>
<div>
<p><inputtype="submit"/><spanid="status_container"></span></p>
</div>
</fieldset>
</form>
</body>
</html>
上面看代码可以看出他通过/gsh/oauth/encryption?generateKeypair=true来先请求获取public 然后通过jcryption进行加密然后post到服务端。Encryption就是上面的EncryptionServlet。
通过浏览器工具可以看到表单里面的数据加密为
jCryption=95f1589502288050e08b4bd8b1a360341cf616d9054531b85a6ef85783c1723b46686ec454ee81f1304fa2370ce24c4d9c06f84d47aa4bdf99310ae12b514db19bfcc325f3a39a584c23b1546550f4e0635c12486f2fd84dec137e1c61cfa775dfa3057a1f0154712aaba0af0cc61810282780f15bed909c24a184e66ab39f2e
3.目标servlet(authorization)的解密
publicclassAuthorization extends HttpServlet {
protectedvoiddoGet(HttpServletRequest httpServletRequest,
HttpServletResponsehttpServletResponse) throws ServletException,
IOException{
PrintWriter out = httpServletResponse.getWriter();
KeyPair keys = (KeyPair)httpServletRequest.getSession().getAttribute("keys");
String encrypted =httpServletRequest.getParameter("epCryption");
String client_id = null;
Stringredirect_uri = null;
Stringloginid = null;
Stringpassword = null;
try {
Stringdata = JCryptionUtil.decrypt(encrypted, keys);
httpServletRequest.getSession().removeAttribute("keys");
Mapparams = JCryptionUtil.parse(data, "UTF-8");
client_id= (String) params.get("client_id");
redirect_uri= (String) params.get("redirect_uri");
loginid= (String) params.get("loginid");
password = (String)params.get("password");
}catch(Throwable e) {
e.printStackTrace();
}
}
}
上面至少片段,需要相关的js和java问题,请在svn上面获取。另外还需要bcprov-jdk15-1.46.jar
可以在http://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15/1.46
获取。