近期笔者参与了一个银企直连接口改造项目,其中数据加密与签名的解决方案颇具特色,现总结分享给大家。
背景
技术难点
解决方案
加密流程
技术实现
Java应用程序开发
1)工程创建与依赖jar导入
首先查看银行工具包配置文件,获取其依赖类库列表。例如,它依赖1.66版本的Bouncy Castle(一个提供了多种哈希算法和加密算法的第三方库)。
银行工具包配置文件
我们把需要的jar包都下载好,然后在Eclipse中新创建一个Maven工程并把jar包全部导入,并在项目配置文件pom.xml中维护依赖关系。
2)映射程序编写
为加密和解密流程分别创建两个类doEncDec.java和doDecEnc.java,以数据加密为例,关键代码示例如下:
//引入银行工具包import com.psbc.uchain.SecurityTools;//获取Input XMLInputStream ins = in.getInputPayload().getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(ins));String line = "";String source = "";while ((line = br.readLine()) != null)source += line.trim() + '\n';br.close();source.trim();//调用银行工具类加密和签名//使用银行公钥非对称加密String encryptedKey = SecurityTools.asymmetricEncrypt(BANK_PUBKEY, randomNumber);//使用我方私钥进行签名String sign = SecurityTools.sign(MY_PRIKEY, REQDATA);//加密后的数据拼接成XML,并返回//String targetxml = "此处省略";out.getOutputPayload().getOutputStream().write(targetxml.getBytes("UTF-8"));
3)将工程导出成jar包
右键工程->Run As->Maven install 或 Maven build
操作路径
此处使用Maven是为了方便把所有依赖类库都打包到jar中,否则在导入SAP PI之后会因缺失关键类库而导致映射失败。注意,导出后的文件包中原始jar可以删掉,避免文件过大。
导出文件一览
PI接口配置
1)定义参数结构
将密钥、明文作为请求参数传入,加密后的密文和签名作为返回参数。
请求和返回参数结构
2)导入jar包
创建Imported Archive对象,将Maven导出的Jar包导入。
Imported Archive对象
3)创建映射
创建Operation Mapping对象,映射程序选择我们导入的Java类。
Operation Mapping对象
-
ERP端程序开发
1)SPROXY更新接口代理
2)应用程序与接口开发调整
-
接口测试验证
如下图所示,接口加密、解密均正常
测试结果
常见问题
工具类缺失
使用Maven打包项目时,注意把依赖包也带出,可以在pom.xml配置文件中激活相应插件功能,如下图所示:
激活assembly插件
类库版本不一致
此类问题比较棘手,具体报错示例如下:
org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey(loaded by library:com.sap.aii.adapter.bouncycastle.lib@63238)cannot be cast toorg.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey(loaded by com.sap.aii.ib.server.mapping.execution.MappingLoader@925449)
它的意思是Java Mapping中使用的BC版本与JVM中静态加载的BC版本不一致,无法完成类型转换。笔者此案例中PI的BC版本是1.59,不符合要求(PSBC最低要求1.66)。
PI中的BC版本
如何以最小代价解决这个问题呢?Deepseek给出了终极解决方案:深度重命名。即反编译工具类,将依赖的BC包名和路径替换为自定义名称,强制使用我们导入版本的BC类库。具体操作如下:
1)首先使用反编译工具修改银行工具类代码
//此时还是标准类库的路径import org.bouncycastle.jce.provider.BouncyCastleProvider;//原逻辑:使用系统静态加载的BC提供者,即1.59版本//KeyFactory localKeyFactory = KeyFactory.getInstance("EC", "BC");//替换后逻辑:不使用静态加载类,直接指定BouncyCastleProvider customProvider = new BouncyCastleProvider();KeyFactory localKeyFactory = KeyFactory.getInstance("EC", customProvider);
2)激活Maven shade插件
修改pom.xml文件,激活shade插件,并设置要替换的BC新路径
激活shade插件
3)重新执行Maven build命令,编译整个工程类并导出jar包
检查新导出的Jar包,发现依赖路径已经替换了
路径成功替换
使用反编译工具查看工具类,发现依赖的BC路径也成功替换
工具类重编译
将此工具包重新导入PI,测试验证Java Mapping成功执行,问题解决。
SSL/TLS加密套件不兼容
本案例中使用Maven较为频繁,联网从云端库自动下载jar包时会遇到如下错误:
javax.net.ssl.SSLHandshakeException: No negotiable cipher suite
--------关注我,解锁更多小技巧-------
参考链接:
https://community.sap.com/t5/technology-blog-posts-by-members/how-to-create-java-mapping-in-sap-pi-po/ba-p/13168046
https://help.sap.com/docs/SUPPORT_CONTENT/xi/3362977038.html?locale=en-US
https://help.sap.com/docs/SUPPORT_CONTENT/xi/3362977397.html?locale=en-US
https://community.sap.com/t5/technology-q-a/sap-po-7-5-custom-adapter-module-cannot-be-cast-to-com-sap-aii-adapter-xi/qaq-p/11943800
https://blog.csdn.net/weixin_42997554/article/details/122561488
往期推荐

