文档章节

银联支付sdk乱塞全局加解密算法,导致的支付宝加解密类乱码的问题

j
 janwenjohn
发布于 2015/07/21 13:31
字数 755
阅读 91
收藏 0

本文转自我的博客,转载请申明地址:http://www.heartlifes.com/archives/4/

背景:###

1.现在版本的支付宝wap支付需要到支付宝后台获取一个token,该字段是加密返回的,需要调用RSA类进行解密 2.银联APP支付是直接给sdk包,然后调用sdk包做tn获取的,内部调用是个黑盒,开发是看不到的

现象:###

1.在不调用银联APP SDK进行初始化的情况下,支付宝WAP支付整体流程都是正确的,token能拿到,也能正常解密 2.在进行一次银联支付后,即银联SDK初始化后,支付宝WAP支付开始一直报错,现象为token加密字符串能获取,但是解密一直是乱码

原因:###

查看银联SDK后,发现在其CertUtil中有个init()静态方法,其调用方法中,有以下两行坑爹代码:

Security.insertProviderAt(new BouncyCastleProvider(), 1);
Security.addProvider(new BouncyCastleProvider());

这两行代码是什么意思呢? 在Security全局上下文环境,将BouncyCastleProvider这个算法类,直接变成默认算法类 导致了什么结果呢? 当你调用支付宝提供的RSA类的时候,默认的算法类从JDK自带的SUN RSA,变成了这个BouncyCastleProvider提供的RSA算法,直接导致和支付宝的加密算法不匹配,于是报错乱码。

解决:###

修改RSA类如下,手动指定算法的provider类

public class RSA {
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
	/**
	 * RSA验签名检查
	 * 
	 * @param content
	 *            待签名数据
	 * @param sign
	 *            签名值
	 * @param ali_public_key
	 *            支付宝公钥
	 * @param input_charset
	 *            编码格式
	 * @return 布尔值
	 */
	public static boolean verify(String content, String sign,
			String ali_public_key, String input_charset) {
		try {
			Provider provider = Security.getProvider("SunRsaSign");
			KeyFactory keyFactory = KeyFactory.getInstance("RSA", provider);
			byte[] encodedKey = Base64.decode(ali_public_key);
			PublicKey pubKey = keyFactory
					.generatePublic(new X509EncodedKeySpec(encodedKey));
			java.security.Signature signature = java.security.Signature
					.getInstance(SIGN_ALGORITHMS, provider);
			signature.initVerify(pubKey);
			signature.update(content.getBytes(input_charset));
			boolean bverify = signature.verify(Base64.decode(sign));
			return bverify;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * 解密
	 * 
	 * @param content
	 *            密文
	 * @param private_key
	 *            商户私钥
	 * @param input_charset
	 *            编码格式
	 * @return 解密后的字符串
	 */
	public static String decrypt(String content, String private_key,
			String input_charset) throws Exception {
		System.out.println("alipay decrypt content..." + content);
		System.out.println("alipay decrypt key..." + private_key);
		PrivateKey prikey = getPrivateKey(private_key);
		Provider provider = Security.getProvider("SunJCE");
		Cipher cipher = Cipher.getInstance("RSA", provider);
		cipher.init(Cipher.DECRYPT_MODE, prikey);
		InputStream ins = new ByteArrayInputStream(Base64.decode(content));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
		byte[] buf = new byte[128];
		int bufl;
		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;
			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}
			writer.write(cipher.doFinal(block));
		}
		return new String(writer.toByteArray(), input_charset);
	}
	/**
	 * 得到私钥
	 * 
	 * @param key
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String key) throws Exception {
		byte[] keyBytes;
		keyBytes = Base64.decode(key);
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		Provider provider = Security.getProvider("SunRsaSign");
		KeyFactory keyFactory = KeyFactory.getInstance("RSA", provider);
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}
}

最后吐槽一下银联的SDK,拜托大哥你以后代码写的不要那么暴力,稍微低调点OK?这么修改全局参数,直接会导致工程中其它加解密类全部趴窝

© 著作权归作者所有

j
粉丝 0
博文 10
码字总数 5840
作品 0
闸北
私信 提问
从支付宝SDK的支付流程理解什么是公钥和私钥,什么是加密和数字签名

名词解释 什么是公钥和私钥 首先要明白公钥和私钥只是一个相对概念,就是说我们不能单纯的去称呼一对密钥中的一个为公钥,另一个为私钥,它们的公私性总是相对于生成者来说的。一对密钥生成后...

码代码的小司机
2018/11/07
106
0
Apple Pay 应用内支付流程分析

接入方式 Apple Pay接入方式的选择上有两种。一种是使用 CUP SDK(CUP 就是 China Union Pay)等第三方的 SDK。另外一种就是使用 iOS 的 PassKit Framework 和银联的接口来接入。本质上来说,...

背锅侠
2016/02/23
108
0
如何防止Unity3D代码被反编译?

欢迎访问网易云社区,了解更多网易技术产品运营经验。 网易云易盾移动游戏安全技术专家陈士留在2018年Unity技术路演演讲内容中对这个问题有过比较详细的介绍,摘录如下: 防止Unity3D代码被反...

网易云
2018/11/28
0
0
App安全性保障方案

App安全性保障方案 之前晋级考核的时候认识到自己在app安全领域存在薄弱环节,所以这段时间研究了Android应用的安全防护,结合公司的项目特点做出记录和总结;主要包扩两个方面:http接口安全和A...

uncochen
2018/01/03
0
0
Java非对称加密RSA工具类v1.1

依旧是练习的产物,java的加密算法有很多,可惜用起来很痛苦(个人感受),有时间的话打算做个简化过程的所有加密算法工具类,之前已经写过一个包含MD5、SHA1、DES、AES、异或的简单工具类 ...

linin630
2016/09/13
228
0

没有更多内容

加载失败,请刷新页面

加载更多

spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库

先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线,取出物料生产Bean 本文研究spr...

星星之焱
22分钟前
5
0
彻底解决tomcat乱码问题

本地项目请求访问,浏览器中文输出没问题。 部署到服务器上面之后,返回到浏览器的中文就乱码了。 尝试办法: 1.修改tomcat下的conf中的service.xml中的配置信息: 重新启动后,没有效果还是...

诗书易经
38分钟前
5
0
Java开发需要掌握的IDEA插件大全

1、Lombok 解释:这是最基本的插件,2017年就火了,还没用的百度一下吧。 博客链接:Intellij IDEA 安装lombok及使用详解 2、PlantUML integration 解释:各种类之间的关联图,高级开发必备。...

木九天
38分钟前
6
0
python学习10.05:Python range()快速初始化数字列表

实际场景中,经常需要存储一组数字。例如在游戏中,需要跟踪每个角色的位置,还可能需要跟踪玩家的几个最高得分。在数据可视化中,处理的几乎都是由数字(如温度、距离、人口数量、经度和纬度...

太空堡垒185
45分钟前
4
0
java单元测试,PowerMockito模拟方法内new对象

在做单元测试中有时候需要对方法内new出来的对象进行隔离,这是我们需要使用PowerMockito。 添加依赖 <dependency> <groupId>org.powermock</groupId> <artifactId>......

如梦之猿
47分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部