java微信小程序步数encryptedData和开放数据解密的实现

网友投稿 545 2022-11-19


java微信小程序步数encryptedData和开放数据解密的实现

前提:

三个参数,

1.sessionKey(拿openId的时候可以得到)

2.encryptedData(前端提供)

3.iv(前端提供)

一个类,一个方法。

1.类:

import java.nio.charset.Charset;

import java.util.Arrays;

/**

* 微信小程序加解密

* @author liuyazhuang

*

*/

public class WxPKCS7Encoder {

private static final Charset CHARSET = Charset.forName("utf-8");

private static final int BLOCK_SIZE = 32;

/**

* 获得对明文进行补位填充的字节.

*

* @param count

* 需要进行填充补位操作的明文字节个数

* @return 补齐用的字节数组

*/

public static byte[] encode(int count) {

// 计算需要填充的位数

int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);

if (amountToPad == 0) {

amountToPad = BLOCK_SIZE;

}

// 获得补位所用的字符

char padChr = chr(amountToPad);

String tmp = new String();

for (int index = 0; index < amountToPad; index++) {

tmp += padChr;

}

return tmp.getBytes(CHARSET);

}

/**

* 删除解密后明文的补位字符

*

* @param decrypted

* 解密后的明文

* @return 删除补位字符后的明文

*/

public static byte[] decode(byte[] decrypted) {

int pad = decrypted[decrypted.length - 1];

if (pad < 1 || pad > 32) {

pad = 0;

}

return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);

}

/**

* 将数字转化成ASCII码对应的字符,用于对明文进行补码

*

* @param a

* 需要转化的数字

* @return 转化得到的字符

*/

public static char chr(int a) {

byte target = (byte) (a & 0xFF);

return (char) target;

}

}

2.方法:

import java.io.UnsupportedEncodingException;

import java.security.AlgorithmParameters;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.Security;

import java.security.spec.InvalidParameterSpecException;

import java.util.HashMap;

import javax.annotation.Resource;

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;

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

import org.apache.commons.lang3.StringUtils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import lombok.extern.slf4j.Slf4http://j;

@Slf4j

public class AesCbcUtil {

static {

//BouncyCastle是一个开源的加解密解决方案,主页在http://bouncycastle.org/

Security.addProvider(new BouncyCastleProvider());

}

/**

* AES解密

*

* @param data //密文,被加密的数据

* @param key //秘钥

* @param iv //偏移量

* @param encodingFormat //解密后的结果需要进行的编码

* @param type //0 是其他 1是微信步数

* @return

* @throws Exception

*/

public static String decrypt(String data, String key, String iv, String encodingFormat,Integer type) throws Exception {

// initialize();

if(StringUtils.isEmpty(data)||StringUtils.isEmpty(key)||StringUtils.isEmpty(iv))

throw new SkyParamNullException("小程序获取用户信息参数不能为空");

//被加密的数据

byte[] dataByte = Base64.decodeBase64(data);

//加密秘钥

byte[] keyByte = Base64.decodeBase64(key);

//偏移量

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

try {

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

SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");

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

parameters.init(new IvParameterSpec(ivByte));

cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化

byte[] resultByte = cipher.doFinal(dataByte);

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

if (type==1){

return new String(WxPKCS7Encoder.decode(resultByte));

}else {

return new String(resultByte, encodingFormat);

}

}

return null;

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

log.error("小程序解析出错1{}",e.getMessage());

} catch (NoSuchPaddingException e) {

e.printStackTrace();

log.error("小程序解析出错2{}",e.getMessage());

} catch (InvalidParameterSpecException e) {

e.printStackTrace();

log.error("小程序解析出错3{}",e.getMessage());

} catch (InvalidKeyException e) {

e.printStackTrace();

log.error("小程序解析出错4{}",e.getMessage());

} catch (InvalidAlgorithmParameterException e) {

e.printStackTrace();

log.error("小程序解析出错5{}",e.getMessage());

} catch (IllegalBlockSizeException e) {

e.printStackTrace();

log.error("小程序解析出错6{}",e.getMessage());

} catch (BadPaddinhttp://gException e) {

e.printStackTrace();

log.error("小程序解析出错7{}",e.getMessage());

}

catch (UnsupportedEncodingException e) {

e.printStackTrace();

log.error("小程序解析出错8{}",e.getMessage());

}

return null;

}

}

实现

@ApiOperation(value = "wx步数解密")

@PostMapping(value = "/decode")

public ResultModel questionList(@RequestBody WxSportParam param) throws Exception {

HashMap map = wxXiaoChenXuUtil.getWxOpenId(//这个方法网上很多,没有就用binarywang的

param.getCode()//前端提供的code

,sysProperties.getWxAppId()//appID

,sysProperties.getWxAppSecret());//secret

String sessionKey = map.get("session_key").toString();

String result = AesCbcUtil.decrypt(param.getData(), sessionKey,param.getIv(), "UTF-8",1);

return ResultModel.success(result);

}

出来的数据 :

{ “stepInfoList”: [

{

“timestamp”: 1445866601,

“step”: 100

},

{

“timestamp”: 1445876601,

“step”: 120

} ] }

tips:如果是解析用户信息的话一样的用法,解密decrypt中参数type传0。两者区别在于字节的decode方法不一样而已。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:注入jar包里的对象,用@autowired的实例
下一篇:Spring事务失效场景原理及解决方案
相关文章

 发表评论

暂时没有评论,来抢沙发吧~