java 小程序开发PKCS7Padding 解密方法实现,以及错误Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
近日在对接小程序API,其中wx.getUserInfo api返回的数据encryptedData 的解密算法要求为: AES-128-CBC,数据采用PKCS#7填充。
经过一番查询,得到java自带了PKCS5Padding算法实现,但是没有PKCS7Padding(注:说的应该是jdk8之前的版本,jdk8的版本有)。需要借助BouncyCastle组件来实现。于是加了如下依赖:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
并写了如下代码:
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class DecryptUtil {
private static final Logger log = Logger.getLogger(DecryptUtil.class);
private static final String AES ="AES";
private static final String AES_CBC_PKCS7 ="AES/CBC/PKCS7Padding";
/**
* <p>对小程序wx.getUserInfo 返回的数据进行解密</p>
*
* <br>开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptedData )进行对称解密。 解密算法如下:</br>
* <li>对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充</li>
* <li>对称解密的目标密文为 Base64_Decode(encryptedData)</li>
* <li>对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。</li>
* <li>对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回</li>
*
* @param encryptedData 小程序wx.getUserInfo接口返回的密文
* @param sessionKey 会话key
* @param iv 小程序接口返回的初始向量
* @return {"openId":"oJ1P50LFpYwzZYaPhV1bjOrM2etY","nickName":"dimi","gender":1,"language":"zh_CN","city":"Haidian","province":"Beijing","country":"CN","avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJjUAIicI0k90UNwz7tTyWt46HrMMaxgSFPcR7Zh0MKZ4vzKibht4Sy3SrTwmYWoFSFOZOE0O1QJ0GQ/0","unionId":"orZ7js0oYCV859piu1kybaWlKGVc","watermark":{"timestamp":1493360456,"appid":"wxe87de3069cac4cf9"}}
* @throws WechatBusinessException
*/
public static String decryptJsUserInfo(String encryptedData,String iv,String sessionKey) {
try {
byte[] data = Base64.decode(encryptedData);
byte[] aseKey = Base64.decode(sessionKey);
byte[] ivData = Base64.decode(iv);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS7);
Key sKeySpec = new SecretKeySpec(aseKey, AES);
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIv(ivData));// 初始化
byte[] result = cipher.doFinal(data);
return new String(result);
} catch (Exception e) {
log.error("=======>小程序用户信息解密失败:"+e);
return null;
}
}
public static AlgorithmParameters generateIv(byte[] iv) throws Exception{
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
public static void main(String[] args){
}
}
结果在本机jdk1.8的环境运行单元测试,解密成功。放到测试环境tomcat之后,解密失败,(在jdk1.7环境下运行都会失败)并报错:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding
一番搜索,发现stackoverflow上面也有人碰到了和我一样的问题 :
this is my code:
static {
Security.addProvider(new BouncyCastleProvider());
}
......
final Cipher sifra = Cipher.getInstance("AES/CBC/PKCS7Padding");
Junit works fine but When I deploy my application to weblogic server I got these exception:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding
Can you hlp me what is wrong ?
问题下面的回答:
That's the old strange problem of different versions and missing cryptography files. I believe PKCS5Padding instead of PKCS7Padding will work. Anyway, it has something to do with Unlimited Strength Jurisdiction Policy Files which can be downloaded from Oracle ... or some other missing part or old version of Java Cryptography Extension.
同时,stackoverflow上又有人说:
PKCS7 padding and PKCS5 padding are the same thing.
于是,我把AES/CBC/PKCS7Padding 替换成AES/CBC/PKCS5Padding,也能解密成功,不报错。
这个回答
看了这么多回答之后,虽然有点懵逼,但是最终我还是解决了问题,因为我感觉是PKCS7Padding算法实现的问题,上面提到依赖了bcprov-jdk16,于是我在仓库中搜索 看是否有高版本的实现,结果发现了bcprov-ext-jdk16,名字多了个ext,我猜想是可以的,于是下载jar包反编译了一下看看,发现bcprov-jdk16的代码是他的子集。我修改了依赖包:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk16</artifactId>
<version>1.45</version>
</dependency>
修改了这个依赖之后,运行成功。以上,供参考。
java 小程序开发PKCS7Padding 解密方法实现,以及错误Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法的更多相关文章
- java PKCS7Padding 加密Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
在java中用aes256进行加密,但是发现java里面不能使用PKCS7Padding,而java中自带的是PKCS5Padding填充,那解决办法是,通过BouncyCastle组件来让java里 ...
- 关于“Cannot find any provider supporting AES/ECB/PKCS7Padding”问题的解决方案
出现这个问题的原因是:java自带的是PKCS5Padding填充,不支持PKCS7Padding填充 参考:https://stackoverflow.com/questions/20770072/ ...
- 【小程序开发总结】微信小程序开发常用技术方法总结
1.获取input的值 <input bindinput="bindKeyInput" placeholder="输入同步到view中"/> b ...
- 微信小程序开发——苹果手机领取卡券出现参数错误(安卓正常)
异常描述: 微信小程序领取卡券,调用 wx.addCard 接口,安卓手机正常调起领取卡券界面,苹果手机.微信开发者工具中均出现“参数错误”,如图: 异常解析: 安卓手机能正常调起领取界面,那就说明领 ...
- python笔记43-加解密AES/CBC/pkcs7padding
前言 有些公司对接口的安全要求比较高,传参数的时候,不会明文的传输,先对接口加密,返回的数据也加密返回. 目前比较常见的加密方式是AES/CBC/pkcs7padding. AES五种加密模式 在AE ...
- java微信小程序解密AES/CBC/PKCS7Padding
摘要:微信小程序解密建议使用1.6及以上的环境使用maven下载jar包org.bouncycastlebcprov-jdk15on1.55加密类代码importorg.bouncycastle.jc ...
- 微信小程序开发——点击按钮获取用户授权没反应或反应很慢的解决方法
异常描述: 点击按钮获取用户手机号码,有的时候会出现点击无反应或很久之后才弹出用户授权获取手机号码的弹窗,这种情况下,也会出现点击穿透的问题(详见:微信小程序开发——连续快速点击按钮调用小程序api返 ...
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
Visual Studio 2017中使用正则修改部分内容 最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...
- 微信小程序开发(后端Java)
微信使用的开发语言和文件很「特殊」. 小程序所使用的程序文件类型大致分为以下几种: ①WXML(WeiXin Mark Language,微信标记语言) ②WXSS(WeiXin Style Shee ...
随机推荐
- 洛谷P4178 Tree (算竞进阶习题)
点分治 还是一道点分治,和前面那道题不同的是求所有距离小于等于k的点对. 如果只是等于k,我们可以把重心的每个子树分开处理,统计之后再合并,这样可以避免答案重复(也就是再同一个子树中出现路径之和为k的 ...
- Vivado如何使用命令行创建工程
前言 vivado中采用TCL脚本语言来作为其命令解释语言.除去可以普通的图形界面流程还可以使用tcl脚本创建工程并导入相关源文件. 流程 1.首先还是要打开vivado图形主界面. 2.在某路径 ...
- 模型评估【PR|ROC|AUC】
这里主要讲的是对分类模型的评估. 1.准确率(Accuracy) 准确率的定义是:[分类正确的样本] / [总样本个数],其中分类正确的样本是不分正负样本的 优点:简单粗暴 缺点:当正负样本分布不均衡 ...
- 深入剖析Kubernetes学习笔记:预习篇(01-04)
01 初出茅庐 1.PaaS 项目被大家接纳的一个主要原因? 就是它提供了一种名叫"应用托管". 2.像 Cloud Foundry 这样的 PaaS 项目,最核心的组件是? 一套 ...
- I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- 抓包工具Charles基本用法
我们在进行B/S架构的Web项目开发时,在前端页面与后台交互的调试的时候,通常使用在JSP中加入“debugger;”断点,然后使用浏览器的F12开发者工具来查看可能出错的地方的数据.或者使用Http ...
- 常用的消息队列中间件mq对比
原文地址:https://blog.csdn.net/qq_30764991/article/details/80239076 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量 ...
- spark JAVA 开发环境搭建及远程调试
spark JAVA 开发环境搭建及远程调试 以后要在项目中使用Spark 用户昵称文本做一下聚类分析,找出一些违规的昵称信息.以前折腾过Hadoop,于是看了下Spark官网的文档以及 github ...
- C++实现递归版二分搜索算法
无聊撸了一个,没啥技术含量,别吐槽.. #include <iostream> using namespace std; int BinarySearch(int* nums,int ke ...
- 一些Js操作
一.after()和before()方法的区别 after()——其方法是将方法里面的参数添加到jquery对象后面去: 如:A.after(B)的意思是将B放到A后面去: before( ...