RSA 签名 / 验签工具

本贴最后更新于 2299 天前,其中的信息可能已经渤澥桑田

依赖 jar 包下载

zmxysdkjava20170605134301.jar
zmxysdkjava20170605134301source.jar

代码如下

import com.antgroup.zmxy.openplatform.api.ZhimaApiException; import com.antgroup.zmxy.openplatform.api.internal.util.Base64Util; import com.antgroup.zmxy.openplatform.api.internal.util.CoderUtil; import com.antgroup.zmxy.openplatform.api.internal.util.EncryptionModeEnum; import com.antgroup.zmxy.openplatform.api.internal.util.SignTypeEnum; import com.antgroup.zmxy.openplatform.api.internal.util.json.ExceptionErrorListener; import com.antgroup.zmxy.openplatform.api.internal.util.json.JSONValidatingReader; import java.io.ByteArrayOutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Iterator; import java.util.Map; import javax.crypto.Cipher; import org.apache.log4j.Logger; public class PKRSACoderUtil extends CoderUtil{ protected static Logger log = Logger.getLogger(PKRSACoderUtil.class); public static final String KEY_ALGORTHM = "RSA"; public static final String SPECIFIC_KEY_ALGORITHM = "RSA/ECB/PKCS1Padding"; public static final String SIGNATURE_ALGORITHM = "SHA256WITHRSA"; public static String encrypt(String paramsString, String charset, String publicKey) throws Exception { byte[] encryptedResult = encryptByPublicKey(paramsString.getBytes(charset), publicKey, null); return Base64Util.byteArrayToBase64(encryptedResult); } public static String encrypt(String paramsString, String charset, String publicKey, EncryptionModeEnum encryptionType) throws Exception { byte[] encryptedResult = encryptByPublicKey(paramsString.getBytes(charset), publicKey, encryptionType); return Base64Util.byteArrayToBase64(encryptedResult); } public static String sign(String data, String charset, String privateKey) throws Exception { byte[] dataInBytes = data.getBytes(charset); String signParams = sign(dataInBytes, privateKey); return signParams; } public static String sign(SignTypeEnum signType, String data, String charset, String privateKey) throws Exception { byte[] dataInBytes = data.getBytes(charset); String signParams = sign(signType, dataInBytes, privateKey); return signParams; } public static String decrypt(String data, String key, String charset) throws Exception { byte[] byte64 = Base64Util.base64ToByteArray(data); byte[] encryptedBytes = decryptByPrivateKey(byte64, key, null); return new String(encryptedBytes, charset); } public static String decrypt(String data, String key, String charset, EncryptionModeEnum encryptionType) throws Exception { byte[] byte64 = Base64Util.base64ToByteArray(data); byte[] encryptedBytes = decryptByPrivateKey(byte64, key, encryptionType); return new String(encryptedBytes, charset); } public static byte[] decryptByPrivateKey(byte[] data, String key, EncryptionModeEnum encryptionType) throws Exception { byte[] decryptedData = null; byte[] keyBytes = decryptBASE64(key); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(2, privateKey); int maxDecryptBlockSize; if (encryptionType != null) maxDecryptBlockSize = getMaxDecryptBlockSizeByEncryptionType(encryptionType); else { maxDecryptBlockSize = getMaxDecryptBlockSize(keyFactory, privateKey); } ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < dataLength; i += maxDecryptBlockSize) { int decryptLength = (dataLength - i < maxDecryptBlockSize) ? dataLength - i : maxDecryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, decryptLength); bout.write(doFinal); } decryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return decryptedData; } public static byte[] encryptByPublicKey(byte[] data, String key, EncryptionModeEnum encryptionType) throws Exception { byte[] encryptedData = null; byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(1, publicKey); int maxEncryptBlockSize; if (encryptionType != null) maxEncryptBlockSize = getMaxEncryptBlockSizeByEncryptionType(encryptionType); else { maxEncryptBlockSize = getMaxEncryptBlockSize(keyFactory, publicKey); } ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < data.length; i += maxEncryptBlockSize) { int encryptLength = (dataLength - i < maxEncryptBlockSize) ? dataLength - i : maxEncryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, encryptLength); bout.write(doFinal); } encryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return encryptedData; } public static String sign(byte[] data, String privateKey) throws Exception { return sign(SignTypeEnum.SHA1WITHRSA, data, privateKey); } public static String sign(SignTypeEnum signType, byte[] data, String privateKey) throws Exception { byte[] keyBytes = decryptBASE64(privateKey); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance(signType.getDesc()); signature.initSign(privateKey2); signature.update(data); return encryptBASE64(signature.sign()); } public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { return verify(SignTypeEnum.SHA1WITHRSA, data, publicKey, sign); } public static boolean verify(SignTypeEnum signType, byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = decryptBASE64(publicKey); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec); Signature signature = Signature.getInstance(signType.getDesc()); signature.initVerify(publicKey2); signature.update(data); return signature.verify(decryptBASE64(sign)); } public static String decryptResponse(String fullResponse, String privateKey, String charset, EncryptionModeEnum encryptionType) throws Exception { String decryptedRsp = null; Map rootJson = parseResponseMap(fullResponse); for (Iterator it = rootJson.keySet().iterator(); it.hasNext(); ) { String key = (String)it.next(); if (key.endsWith("_response")) { String value = (String)rootJson.get(key); decryptedRsp = value; } } if (((Boolean)rootJson.get("encrypted")).booleanValue()) { decryptedRsp = decrypt(decryptedRsp, privateKey, charset, encryptionType); } return decryptedRsp; } public static void verifySign(String fullResponse, String decryptedBizResponse, String publicKey, String charset) throws Exception { verifySign(SignTypeEnum.SHA1WITHRSA, fullResponse, decryptedBizResponse, publicKey, charset); } public static void verifySign(SignTypeEnum signType, String fullResponse, String decryptedBizResponse, String publicKey, String charset) throws Exception { Map rootJson = parseResponseMap(fullResponse); String sign = (String)rootJson.get("biz_response_sign"); if ((sign != null) && (sign.length() > 0)) { boolean success = verify(signType, decryptedBizResponse.getBytes(charset), publicKey, sign); if (!(success)) throw new ZhimaApiException("验签失败: " + sign.toString()); } } public static Map parseResponseMap(String fullResponse) throws ZhimaApiException { JSONValidatingReader reader = new JSONValidatingReader(new ExceptionErrorListener()); Object rootObj = reader.read(fullResponse); if (rootObj instanceof Map) { Map rootJson = (Map)rootObj; return rootJson; } throw new ZhimaApiException("返回结果格式有误:" + fullResponse); } private static int getMaxEncryptBlockSize(KeyFactory keyFactory, Key key) throws Exception { int maxLength = 117; try { RSAPublicKeySpec publicKeySpec = (RSAPublicKeySpec)keyFactory.getKeySpec(key, RSAPublicKeySpec.class); int keyLength = publicKeySpec.getModulus().bitLength(); maxLength = keyLength / 8 - 11; } catch (Exception e) { } return maxLength; } private static int getMaxEncryptBlockSizeByEncryptionType(EncryptionModeEnum encryptionType) { if (encryptionType == EncryptionModeEnum.RSA1024) return 117; if (encryptionType == EncryptionModeEnum.RSA2048) { return 245; } return 117; } private static int getMaxDecryptBlockSize(KeyFactory keyFactory, Key key) throws Exception { int maxLength = 128; try { RSAPrivateKeySpec publicKeySpec = (RSAPrivateKeySpec)keyFactory.getKeySpec(key, RSAPrivateKeySpec.class); int keyLength = publicKeySpec.getModulus().bitLength(); maxLength = keyLength / 8; } catch (Exception e) { } return maxLength; } private static int getMaxDecryptBlockSizeByEncryptionType(EncryptionModeEnum encryptionType) { if (encryptionType == EncryptionModeEnum.RSA1024) return 128; if (encryptionType == EncryptionModeEnum.RSA2048) { return 256; } return 128; } }

验签代码

/** * 验证签名 * @return * @throws Exception */ public static boolean checksign(JSONObject jsonObject,String platpublickey) throws Exception{ //获取签名 String sign = jsonObject.getString("sign"); //json对象转换成map Map<String,Object> bizParams = getTextParams(jsonObject); String content = unurlgetSignCheckContentV2(bizParams).trim().replace("\\/", "/"); return PKRSACoderUtil.verify(SignTypeEnum.SHA256WITHRSA, content.getBytes(SysUtil.CHARSET),platpublickey, sign); }

签名代码

/** * 生成签名 * * * @return * */ public static String producesignByJson(JSONObject jsonObject ,String zzrsprivatekey){ String signstr=""; try{ String content = unurlgetSignCheckContentV2(getTextParams(jsonObject)).trim(); signstr = PKRSACoderUtil.sign(SignTypeEnum.SHA256WITHRSA, content, SysUtil.CHARSET, zzrsprivatekey); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return signstr; }
  • RSA
    8 引用 • 5 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 133 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 108 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖
  • Visio
    1 引用 • 2 回帖 • 2 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    497 引用 • 934 回帖
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 1 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    246 引用 • 1338 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 88 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 543 回帖 • 2 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 649 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1127 回帖 • 110 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 766 关注
  • 叶归
    13 引用 • 59 回帖 • 22 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 395 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖 • 1 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    25 引用 • 254 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 77 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 713 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 9 关注
  • V2Ray
    1 引用 • 15 回帖 • 4 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    188 引用 • 319 回帖 • 237 关注