获取微信小程序加密后的敏感数据

	/**
	 * 解密用户敏感数据
	 * @param encryptedData 明文
	 * @param iv            加密算法的初始向量
	 * @param code     微信code
	 * @return
	 */
	@RequestMapping("/decodeUserInfo")
	@ResponseBody
	public ResultVO decodeUserInfo(String encryptedData, String iv, String code){
		ResultVO res=new ResultVO();
		try {
			// 获取微信小程序的session_key
			Sessionkey sessionKey = WeiXinApi.getSessionKey(Constant.APPID, Constant.APPSECRET, code);
			String session_key = sessionKey.getSession_key();
			if(StringUtils.isEmpty(session_key)){
				res.setMsg("获取sessionKey错误");
				res.setCode(Code.FAIL_CODE);
				return res;
			}
			// 解密敏感数据
			String ret = WXBizMsgCrypt.decrypt(encryptedData, session_key, iv, "UTF-8");
			if(StringUtils.isNotBlank(ret)){
				JSONObject jsonObject = JSONObject.parseObject(ret);
				String purePhoneNumber = jsonObject.getString("purePhoneNumber");
				res.setCode(Code.SUCCESS_CODE);
				res.setMsg(Code.SUCCESS_MSG);
				System.out.println(purePhoneNumber);
				res.setResult(purePhoneNumber);
				return res;
			}
		} catch (Exception e) {
			logger.error(e);
		}
		return res;
	}

在这里插入图片描述

/**
 * 针对org.apache.commons.codec.binary.Base64,
 * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
 * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
 * 解密获取微信小程序加密后的手机号
 */
public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
		try {
			//被加密的数据
			byte[] dataByte = Base64.decodeBase64(data);
			//加密秘钥
			byte[] keyByte = Base64.decodeBase64(key);
			//偏移量
			byte[] ivByte = Base64.decodeBase64(iv);
			// 初始化:					 加解密算法/模式/填充方式
			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
			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) {
				return new String(resultByte, encodingFormat);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

以上解密过程会产生异常,原因是java原生jdk不支持PKCS7Padding填充方式
解决方式 请看博文:https://blog.csdn.net/qq_43225978/article/details/94459412

注:

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

其中的 "BC"需要加上,不然会报异常:

javax.crypto.BadPaddingException: pad block corrupted

原因:因为BC是一个provider,而org.bouncycastle.jce.provider.BouncyCastleProvider是个第三方的库。如果jce自带的就可以不用加BC,但是JCE不支持PKCS7Padding的填充方式。

借鉴文章:
https://www.cnblogs.com/chen-lhx/p/6233954.html
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#加密数据解密算法
https://blog.csdn.net/yuanhangLVli/article/details/82152178

posted @ 2021-04-19 15:36  IT-小浣熊  阅读(167)  评论(0)    收藏  举报