(转)JAVASCRIPT端加密JAVA服务端解密

http://www.blogjava.net/linugb118/archive/2014/05/09/413459.html

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;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;



import com.gsh.oauth.auth.util.JCryptionUtil;



/**

* Servlet implementation class EncryptionServlet

*/

public class EncryptionServlet extends HttpServlet {

private static final long serialVersionUID = 1L;



/**

* Default constructor.

*/

public EncryptionServlet() {

// TODO Auto-generated constructor stub

}



/**

* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)

*/

protected void service(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

int KEY_SIZE = 1024;

if (request.getParameter("generateKeypair") != null) {



JCryptionUtil jCryptionUtil = new JCryptionUtil();



KeyPair keys = null;

//if (request.getSession().getAttribute("keys") == null) { //这里注释掉 否则第二次请求会500

keys = jCryptionUtil.generateKeypair(KEY_SIZE);

request.getSession().setAttribute("keys", keys);

//}



StringBuffer output = new StringBuffer();



String e = JCryptionUtil.getPublicKeyExponent(keys);

String n = JCryptionUtil.getPublicKeyModulus(keys);

String md = String.valueOf(JCryptionUtil.getMaxDigits(KEY_SIZE));



output.append("{\"e\":\"");

output.append(e);/Files/linugb118/bcprov-jdk15-1.46.jar.zip

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>

<meta http-equiv="Content-Type"

content="text/html; charset=utf-8">



<script src="../js/jquery-1.4.2.min.js" type="text/javascript"></script>

<script src="../js/jquery-ui-1.8.2.custom.min.js"

type="text/javascript"></script>

<script type="text/javascript"

src="../js/security/jquery.jcryption-1.1.min.js"></script>



<script type="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();

return true;

},

encryptionFinished : function(

encryptedString,

objectLength) {

$statusText

.text(encryptedString);

return true;

}

});

});

</script>

<body>



<form id="lf" action="/gsh/oauth/authorization"

method="post">

<fieldset><legend>login</legend>

<div>

<div>client_id:<br>

<input type="text" size="45" name="client_id" value=""></div>

<div>redirect_uri:<br>

<input type="text" size="45" name="redirect_uri" value=""></div>

</div>

<div>loginid:<br>

<input type="text" size="45" name="loginid" value=""></div>

</div>

<div>password:<br>

<input type="password" size="45" name="password" value=""></div>

</div>

<div>

<p><input type="submit" /><span id="status_container"></span></p>

</div>

</fieldset>

</form>

</body>

</html>



上面看代码可以看出 他通过/gsh/oauth/encryption?generateKeypair=true来先请求获取public 然后通过jcryption进行加密 然后post到服务端。Encryption就是上面的EncryptionServlet。

通过浏览器工具可以看到表单里面的数据加密为



jCryption=95f1589502288050e08b4bd8b1a360341cf616d9054531b85a6ef85783c1723b46686ec454ee81f1304fa2370ce24c4d9c06f84d47aa4bdf99310ae12b514db19bfcc325f3a39a584c23b1546550f4e0635c12486f2fd84dec137e1c61cfa775dfa3057a1f0154712aaba0af0cc61810282780f15bed909c24a184e66ab39f2e

3. 目标servlet(authorization)的解密



public class Authorization extends HttpServlet {



protected void doGet(HttpServletRequest httpServletRequest,

HttpServletResponse httpServletResponse) throws ServletException,

IOException {



PrintWriter out = httpServletResponse.getWriter();



KeyPair keys = (KeyPair) httpServletRequest.getSession().getAttribute("keys");

String encrypted = httpServletRequest.getParameter("epCryption");



String client_id = null;

String redirect_uri = null;

String loginid = null;

String password = null;



try {

String data = JCryptionUtil.decrypt(encrypted, keys);

httpServletRequest.getSession().removeAttribute("keys");

Map params = 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

获取。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序本身是运行在微信客户中的,无法直接使用 Java 调用 `getPhoneNumber()` 方法。如果你想在服务使用 Java 调用微信小程序的 `getPhoneNumber()` 方法,你需要先在小程序中获取用户的加密数据、初始向量和会话密钥,然后将这些数据发送到服务,再在服务使用 Java 解密用户手机号。 以下是一个简单的示例,演示了如何在小程序中获取用户手机号的加密数据、初始向量和会话密钥,并将这些数据发送到服务: ```javascript // 在小程序中获取用户手机号的加密数据、初始向量和会话密钥 wx.login({ success: function(res) { wx.request({ url: 'https://api.weixin.qq.com/sns/jscode2session', data: { appid: 'YOUR_APPID', secret: 'YOUR_SECRET', js_code: res.code, grant_type: 'authorization_code' }, success: function(res) { var sessionKey = res.data.session_key; var encryptedData = 'ENCRYPTED_DATA'; // 用户数据的加密数据 var iv = 'IV'; // 加密算法的初始向量 wx.request({ url: 'https://YOUR_DOMAIN.com/getPhoneNumber', // 发送加密数据到服务 data: { sessionKey: sessionKey, encryptedData: encryptedData, iv: iv }, success: function(res) { console.log(res.data); } }) } }) } }) ``` 在服务中,你需要使用 Java 代码解密用户手机号的加密数据,具体步骤如下: 1. 使用 Java 中的 Base64 类将加密数据和初始向量进行解码。 2. 使用 Java 中的 Cipher 类进行解密解密算法使用 AES/CBC/PKCS5Padding。 3. 将解密后的数据换成 JSON 对象,从中获取用户手机号和区号。 以下是一个简单的示例,演示了如何在 Java 代码中解密用户手机号的加密数据: ```java import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidParameterSpecException; import java.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class DecryptPhoneNumber { public static void main(String[] args) { String sessionKey = "SESSION_KEY"; // 用户数据的会话密钥,需要前传递过来 String encryptedData = "ENCRYPTED_DATA"; // 用户数据的加密数据,需要前传递过来 String iv = "IV"; // 加密算法的初始向量,需要前传递过来 try { byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey); byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData); byte[] ivBytes = Base64.getDecoder().decode(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decryptedData = cipher.doFinal(encryptedDataBytes); String decryptedDataStr = new String(decryptedData, "UTF-8"); System.out.println(decryptedDataStr); // 解析 JSON 对象,获取用户手机号和区号 // ... } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidParameterSpecException e) { e.printStackTrace(); } } } ``` 这只是一个简单的示例,实际使用中还需要注意数据的格式和安全性等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值