RSA 签名 / 验签工具

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

依赖 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 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 405 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 3 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 121 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 1 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 494 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 366 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    171 引用 • 1537 回帖 • 1 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 350 关注
  • OneDrive
    2 引用 • 5 关注
  • MongoDB

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

    91 引用 • 59 回帖 • 4 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖
  • ZeroNet

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

    1 引用 • 21 回帖 • 651 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 344 关注
  • 小说

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

    32 引用 • 108 回帖 • 2 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 1 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 544 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 10 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 4 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    372 引用 • 1857 回帖 • 1 关注
  • sts
    2 引用 • 2 回帖 • 241 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 676 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 58 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 365 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 2 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

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

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

    82 引用 • 411 回帖