当前位置:   article > 正文

java调用微信加密_JAVA版微信小程序用户数据的签名验证和加解密

微信小程序授权登录 java 加密 签名

179411124_2_20200102021248316_wm

签名验证和加解密

数据签名校验

为了确保 开放接口 返回用户数据的安全性,微信会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。签名校验算法涉及用户的session_key,通过 wx.login 登录流程获取用户session_key,并自行维护与应用自身登录态的对应关系。

通过调用接口(如 wx.getUserInfo)获取数据时,接口会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )

开发者将 signature、rawData 发送到开发者服务器进行校验。服务器利用用户对应的 session_key 使用相同的算法计算出签名 signature2 ,比对 signature 与 signature2 即可校验数据的完整性。

加密数据解密算法

接口如果涉及敏感数据(如wx.getUserInfo当中的 openId 和unionId ),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptedData )进行对称解密。解密算法如下:对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。

对称解密的目标密文为 Base64_Decode(encryptedData),

对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节

对称解密算法初始向量 iv 会在数据接口中返回。

微信官方提供了多种编程语言的示例代码

(https://mp.weixin.qq.com/debug/wxadoc/dev/demo/aes-sample.zip),

但就是没提供JAVA版本的,可能的确PHP是最好的语言,腾讯提供的demo好多都是PHP版本的。

JAVA代码案例

pom.xml引入以下依赖:

commons-codec

commons-codec

1.10

com.alibaba

fastjson

1.2.7

org.bouncycastle

bcprov-jdk15on

1.57

我们可以参考PHP给出的代码,使用JAVA实现:

AESUtil:import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.AlgorithmParameters;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.Key;

import java.security.NoSuchAlgorithmException;

import java.security.NoSuchProviderException;

import java.security.Security;

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;

/**

* AES解密

*/public class AESUtil{

static {

Security.addProvider(new BouncyCastleProvider());

}

/**

* AES解密

* @param content 密文

* @return

* @throws InvalidAlgorithmParameterException

* @throws NoSuchProviderException

*/

public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte)

throws InvalidAlgorithmParameterException {

try {

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

Key sKeySpec = new SecretKeySpec(keyByte, "AES");            //生成iv

AlgorithmParameters params = AlgorithmParameters.getInstance("AES");

params.init(new IvParameterSpec(ivByte));

cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);// 初始化

return cipher.doFinal(content);

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (NoSuchPaddingException e) {

e.printStackTrace();

} catch (InvalidKeyException e) {

e.printStackTrace();

} catch (IllegalBlockSizeException e) {

e.printStackTrace();

} catch (BadPaddingException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}        return null;

}

}

WXBizDataCrypt:import java.io.UnsupportedEncodingException;

import java.security.InvalidAlgorithmParameterException;

import org.apache.commons.codec.binary.Base64;

import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

/**

* 对微信小程序用户加密数据的解密

*/public class WXBizDataCrypt{

public static String illegalAesKey = "-41001";//非法密钥

public static String illegalIv = "-41002";//非法初始向量

public static String illegalBuffer = "-41003";//非法密文

public static String decodeBase64Error = "-41004"; //解码错误

public static String noData = "-41005"; //数据不正确

private String appid;

private String sessionKey;

public WXBizDataCrypt(String appid, String sessionKey){

this.appid = appid;

this.sessionKey = sessionKey;

}

/**

* 检验数据的真实性,并且获取解密后的明文.

* @param encryptedData  string 加密的用户数据

* @param iv  string 与用户数据一同返回的初始向量

* @return data string 解密后的原文

* @return String 返回用户信息

*/

public String decryptData(String encryptedData, String iv){

if (StringUtils.length(sessionKey) != 24) {

return illegalAesKey;

}

// 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。

byte[] aesKey = Base64.decodeBase64(sessionKey);

if (StringUtils.length(iv) != 24) {

return illegalIv;

}

// 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。

byte[] aesIV = Base64.decodeBase64(iv);

// 对称解密的目标密文为 Base64_Decode(encryptedData)

byte[] aesCipher = Base64.decodeBase64(encryptedData);

try {

byte[] resultByte = AESUtil.decrypt(aesCipher, aesKey, aesIV);

if (null != resultByte && resultByte.length > 0) {

String userInfo = new String(resultByte, "UTF-8");

JSONObject jsons = JSON.parseObject(userInfo);

String id = jsons.getJSONObject("watermark").getString("appid");

if (!StringUtils.equals(id, appid)) {

return illegalBuffer;

}

return userInfo;

} else {

return noData;

}

} catch (InvalidAlgorithmParameterException e) {

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return null;

}

/**

* encryptedData 和 iv 两个参数通过小程序wx.getUserInfo()方法获取

* @param args

* @see

*/

public static void main(String[] args){

String appId = "wx4f4bc4dec97d474b";

String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";

String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM"

+ "QmRzooG2xrDcvSnxIMXFufNstNGTyaGS"

+ "9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+"

+ "3hVbJSRgv+4lGOETKUQz6OYStslQ142d"

+ "NCuabNPGBzlooOmB231qMM85d2/fV6Ch"

+ "evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6"

+ "/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw"

+ "u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn"

+ "/Hz7saL8xz+W//FRAUid1OksQaQx4CMs"

+ "8LOddcQhULW4ucetDf96JcR3g0gfRK4P"

+ "C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB"

+ "6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns"

+ "/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd"

+ "lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV"

+ "oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG"

+ "20f0a04COwfneQAGGwd5oa+T8yO5hzuy"

+ "Db/XcxxmK01EpqOyuxINew==";

String iv = "r7BXXKkLb8qrSNn05n0qiA==";

WXBizDataCrypt biz = new WXBizDataCrypt(appId, sessionKey);

System.out.println(biz.decryptData(encryptedData, iv));

}

}

运行main方法,获取返回结果:{"openId":"oGZUI0egBJY1zhBYw2KhdUfwVJJE","nickName":"Band","gender":1,"language":"z

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/525046
推荐阅读
相关标签
  

闽ICP备14008679号