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 ...
随机推荐
- [模板] k短路
简介 Dijkstra最短路+A*搜索. 先逆向求所有点到终点的最短路 \(dis[i]\). 定义估价函数 \(f[i] = d[i] + dis[i]\) , 其中 \(d[i]\) 表示当前起点 ...
- CSS实现动画特效导航栏
0 写在前面 今天用纯CSS编写了一种带有特效的导航栏,一方面巩固熟悉了导航栏的一般写法,另一方面练习了CSS3的一些新特性. 1 实现效果 当鼠标划过时,实现了一种动态百叶窗效果. 2 实现细节 2 ...
- elk中fliebeat的配置文件
fliebeat----> kafka的配置文件 # cat filebeat.yml|egrep -v "^$|^#"|grep -v "^ #" fi ...
- 分布式监控系统开发【day38】:报警自动升级代码解析及测试(八)
一.报警自动升级代码解析 发送邮件代码 def action_email(self,action_obj,action_operation_obj,host_id,trigger_data): ''' ...
- Entity Framework入门教程(2)---EF工作流程
EF工作流程 1.EF基本CRUD流程 下边的图就可以很清晰地展示EF的CRUD操作的基本工作流程: 这里做一个EF CRUD操作的简单总结:1.定义模型:这是EF工作的前提,定义模型包括定义领域类( ...
- jQuery使用(十三):工具方法
proxy() onConflict() each() map() parseJson() makeArray() proxy() $.proxy()的实现机制与原生javaScript中的bind( ...
- Javaweb学习笔记——(二十三)——————AJAX、XStream、JSON
AJAX概述 1.什么是AJAX ajax(Asynchronous JavaScript and xml) 翻译成中文就是"异步JavaScript和xml&quo ...
- mysql 以数组的形式插入更新表
在项目中用php+mysql,需要插入数据,但是数据库表字段又很长,如果用常规的insert into table (c) values ('dd')的话,将是很长的sql语句,而且一不小心,就弄错了 ...
- Notepad++ --v7.5.8 (64bit) 安装目录显示插件(Explorer)
https://blog.csdn.net/qq_24153697/article/details/83036761 最近想自己做一个小项目,用Notepad做IDE,但是发现已安装的Notepad没 ...
- 分别基于TensorFlow、PyTorch、Keras的深度学习动手练习项目
×下面资源个人全都跑了一遍,不会出现仅是字符而无法运行的状况,运行环境: Geoffrey Hinton在多次访谈中讲到深度学习研究人员不要仅仅只停留在理论上,要多编程.个人在学习中也体会到单单的看理 ...