在做支付的涉及安全的时候,经常会
遇到很多情况,就是合作方在生成公钥和私钥的情况下都喜欢是RSA格式,对方要求未经过PKCS#8编码的私钥文件,这中格式对于js代码很容易实现,但是对于Java来就不是很容易,要多很多代码,笔者在此总结:

笔者在这里提供两种解决办法:

一、RSA转换PKSC8

  • 1.源头解决
生成pem格式的私钥:
openssl genrsa -out private_key.pem 1024生成公钥:
openssl rsa -in private_key.pem -pubout -out public_key.pem

使用下面的方式进行转换

openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out private_key_pkcs8.pem
  • 2.将已经生成的私钥进行转换

RSA转换PKCS8

以上两种方法,均可以使用下面解决

/*** 工具类:* 私钥:openssl genrsa -out /Users/mac/Desktop/private_key.pem 1024* 公钥:openssl rsa -in /Users/mac/Desktop/private_key.pem -out /Users/mac/Desktop/rsa_public_key.pem -pubout** 异常:* algid parse error, not a sequence** 解决办法:* 将rsa转换为pkcs8* http://tool.chacuo.net/cryptrsapkcs1pkcs8* @Auther lx*/
public class SignUtil {public static String text = "war";public static RSAPublicKey rsaPublicKey;public static RSAPrivateKey rsaPrivateKey;public static void main(String[] args) throws Exception {String rsaprivateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMhvuLsBi0FWmuwF\n" +"x2XHZWOBNkzviihv9r0CD2qc0D4rnQW/DO9muIu2zsWLD88Iujk19WE28X85I/pU\n" +"3QMR2NKQ57iNZzX+/vy1LsrF/vZMzJRnN0Xa4OqYYF0KP2ZiXSIqFOyUx2rqgWa8\n" +"YFmfhJGfsmMCpOvHCPV/pokXHDy1AgMBAAECgYB7mREkGD6kCuC7nJCp/XxTENHI\n" +"PYpHh0tyn/ubtZlgTQqmCXrTgddZKGB3Rlp4Q5x6PQDUcsoWtsitzHkBNJcroVR8\n" +"yhD9JaaFWLuJXJoYaTvAFtUzqaSVhuaZfflL57i9FnVhkDeh9rVwp5f9EfO3OrM0\n" +"ez4Q0Q0MnMOEJyCp4QJBAPQI2HNPi4fwgWc6fvrFkf6FDDTRcpn0W5kLNtmmImw+\n" +"IVK1MQgOKT1FXTwsz3pNkhwbbxg5ZskItYg4tYs6NkkCQQDSQ6Bad0xD/TnqzlHP\n" +"krqBPx4dMataXLsDb8b/CcTGeXtEzrVQCxeP6LwhPD7Yrn4lctASXMwqvjn843xT\n" +"36MNAkEA3K0jDyNfig5y9mZvbVY8L20hHKJKf+345uy9LRSPDFMizygKrr4fjMit\n" +"Bz1+YZrEBabJT56Y1DKL9iNSCBUcAQJARObsUTjuwQjmRc++d2r5uwjX8XEpWb8x\n" +"eXrTlxe4Z+G/R1kFiWlZG0uE+s8nORJVPChXjuzh6s/TaM+TGlkasQJAODVjJ2IE\n" +"fXurgMxfsAed8D4ZoDnNPEUIjfJnc9P5Wx5WZHe/CfPgEPbzkl70eI+hvG9Zl/IN\n" +"VKzUByVSsbajcQ==";loadPrivateKey(rsaprivateKey);//TODO 使用SHA256加密解密Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(rsaPrivateKey);signature.update(text.getBytes());byte[] result = signature.sign();System.out.println("SHA256withRSA加密:" + Base64Utils.encodeToString(result));String rsapublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIb7i7AYtBVprsBcdlx2VjgTZM\n" +"74oob/a9Ag9qnNA+K50FvwzvZriLts7Fiw/PCLo5NfVhNvF/OSP6VN0DEdjSkOe4\n" +"jWc1/v78tS7Kxf72TMyUZzdF2uDqmGBdCj9mYl0iKhTslMdq6oFmvGBZn4SRn7Jj\n" +"AqTrxwj1f6aJFxw8tQIDAQAB";loadPublicKey(rsapublicKey);signature.initVerify(rsaPublicKey);signature.update("war".getBytes());boolean flag = signature.verify(result);System.out.println("SHA256withRSA解密:" + flag);}/*** 从字符串中加载公钥** @param publicKeyStr 公钥数据字符串* @throws Exception 加载公钥时产生的异常*/public static void loadPublicKey(String publicKeyStr) throws Exception {try {BASE64Decoder base64Decoder = new BASE64Decoder();byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr);KeyFactory keyFactory = KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (IOException e) {throw new Exception("公钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("公钥数据为空");}}public static void loadPrivateKey(String privateKeyStr) throws Exception {try {BASE64Decoder base64Decoder = new BASE64Decoder();byte[] buffer = base64Decoder.decodeBuffer(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance("RSA");rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (IOException e) {throw new Exception("私钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("私钥数据为空");}}
}

二、直接使用RSA验证签名,多写两行实现

Oracle参考文献

去掉---开头----byte [] asn1PrivateKeyBytes = org.apache.commons.codec.binary.Base64.decodeBase64(b64encoded.getBytes("US-ASCII"));RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(asn1PrivateKeyBytes));RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());KeyFactory kf = KeyFactory.getInstance("RSA");RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(rsaPrivKeySpec);System.out.println(privKey.getPrivateExponent());
     String rsaprivateKey = "MIICXAIBAAKBgQDIb7i7AYtBVprsBcdlx2VjgTZM74oob/a9Ag9qnNA+K50Fvwzv\n" +"ZriLts7Fiw/PCLo5NfVhNvF/OSP6VN0DEdjSkOe4jWc1/v78tS7Kxf72TMyUZzdF\n" +"2uDqmGBdCj9mYl0iKhTslMdq6oFmvGBZn4SRn7JjAqTrxwj1f6aJFxw8tQIDAQAB\n" +"AoGAe5kRJBg+pArgu5yQqf18UxDRyD2KR4dLcp/7m7WZYE0Kpgl604HXWShgd0Za\n" +"eEOcej0A1HLKFrbIrcx5ATSXK6FUfMoQ/SWmhVi7iVyaGGk7wBbVM6mklYbmmX35\n" +"S+e4vRZ1YZA3ofa1cKeX/RHztzqzNHs+ENENDJzDhCcgqeECQQD0CNhzT4uH8IFn\n" +"On76xZH+hQw00XKZ9FuZCzbZpiJsPiFStTEIDik9RV08LM96TZIcG28YOWbJCLWI\n" +"OLWLOjZJAkEA0kOgWndMQ/056s5Rz5K6gT8eHTGrWly7A2/G/wnExnl7RM61UAsX\n" +"j+i8ITw+2K5+JXLQElzMKr45/ON8U9+jDQJBANytIw8jX4oOcvZmb21WPC9tIRyi\n" +"Sn/t+ObsvS0UjwxTIs8oCq6+H4zIrQc9fmGaxAWmyU+emNQyi/YjUggVHAECQETm\n" +"7FE47sEI5kXPvndq+bsI1/FxKVm/MXl605cXuGfhv0dZBYlpWRtLhPrPJzkSVTwo\n" +"V47s4erP02jPkxpZGrECQDg1YydiBH17q4DMX7AHnfA+GaA5zTxFCI3yZ3PT+Vse\n" +"VmR3vwnz4BD285Je9HiPobxvWZfyDVSs1AclUrG2o3E=";byte [] asn1PrivateKeyBytes = org.apache.commons.codec.binary.Base64.decodeBase64(rsaprivateKey.getBytes("US-ASCII"));RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence)ASN1Sequence.fromByteArray(asn1PrivateKeyBytes));RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(),asn1PrivKey.getPrivateExponent());KeyFactory keyFactory= KeyFactory.getInstance("RSA");PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec);//TODO 使用SHA256加密解密Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(priKey);signature.update(text.getBytes());byte[] result = signature.sign();System.out.println("SHA256withRSA加密:" + Base64Utils.encodeToString(result));String rsapublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIb7i7AYtBVprsBcdlx2VjgTZM\n" +"74oob/a9Ag9qnNA+K50FvwzvZriLts7Fiw/PCLo5NfVhNvF/OSP6VN0DEdjSkOe4\n" +"jWc1/v78tS7Kxf72TMyUZzdF2uDqmGBdCj9mYl0iKhTslMdq6oFmvGBZn4SRn7Jj\n" +"AqTrxwj1f6aJFxw8tQIDAQAB";loadPublicKey(rsapublicKey);signature.initVerify(rsaPublicKey);signature.update("test".getBytes());boolean flag = signature.verify(result);System.out.println("SHA256withRSA解密:" + flag);

附录

上面的RSA其实就是PKCS1

PKCS

The Public-Key Cryptography Standards (PKCS)是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。

PKCS已经公布了以下标准:

PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
PKCS#3:定义Diffie-Hellman密钥交换协议[23]。
PKCS#5:描述一种利用从口令派生出来的安全密钥加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息[24]。
PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式[25]。
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息[26]。
PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等[27]。
PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥加密信息的属性类型[28]。
PKCS#10:描述证书请求语法[29]。
PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡之类的加密设备[30]。
PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法[31]。
PKCS#13:椭圆曲线密码体制标准[32]。
PKCS#14:伪随机数生成标准。
PKCS#15:密码令牌信息格式标准[33]。

RSA

1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。
这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

数据安全验证签名问题.RSA 与PKCS8的坑相关推荐

  1. RSA加密、解密、签名、验签(验证签名)RSA算法原理

    转载链接:https://www.jianshu.com/p/8dc4a5f64e06 https://www.cnblogs.com/pcheng/p/9629621.html RSA原理:http ...

  2. 微信支付 支付验证签名失败

    公众号支付,WeixinJSBridge.invoke()方法,返回错误:支付验证签名失败 检查后台签名参数.支付密钥均正确,却还是错误,最后询问微信支付技术才解决,问题所在就是微信给的java sd ...

  3. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  4. .NET Core 使用RSA算法 加密/解密/签名/验证签名

    前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...

  5. 支付宝服务窗验证签名

    <?php /** * Desc 注意生成的私钥和公钥是2048位,PKCS1(PHP使用,如果是java,使用PKCS8),编码GBK,然后用支付宝的秘钥生成公钥来生成.这个网关是为了用来支付 ...

  6. php接口数据加密、解密、验证签名【转】

    <?php /** * 数据加密,解密,验证签名 * @edit http://www.lai18.com * @date 2015-07-08 **/ //header('Content-Ty ...

  7. java数字签名(签名生成,用证书验证签名)

    部分签名原理 http://blog.csdn.net/lijiecong/archive/2010/12/24/6096289.aspx (转载序:网上找的好文章,一篇就把我找了几天的所有东西都概括 ...

  8. AVB之镜像的签名及验证签名详解

    文章目录 1.签名流程 1.1 镜像的签名 1.2 镜像的内容 2.验证镜像的hash和signature签名 2.1 计算hash 2.2 验证签名 1.签名流程 我们以一下空的dtbo.img镜像 ...

  9. java 支付宝回调校验签名_支付宝异步回调验证签名

    今天做支付宝接口回调这块,不得不说,弄的我焦头烂额,翻了很多陈年旧帖,试了无数种解决坑的方案,在我成功解决的一瞬间,觉得非常有必要记录一下这些坑. 签名验证错误的检查顺序(这里是基于使用官方给的dem ...

最新文章

  1. Linux文件IO深入剖析
  2. android 全局进度条,Android:如何在中心显示全屏进度条
  3. python2.6.6安装MySQL-python模块正确方法
  4. 【最短路】【Dijkstra】【图论】最小花费(jzoj 2125)
  5. python随机数模块_python 随机数模块 -- random
  6. 为什么我饿了么产品总监不干,却要从事自由职业?
  7. 成功入职阿里P7后 一个技术老哥总结了这几句话
  8. c语言告白,C语言告白代码,一闪一闪亮晶晶~
  9. 【kafka】kafka 消费报错 Failed to add leader for partitions
  10. jquery 源码分析
  11. SVM入门(四)线性分类器的求解——问题的描述Part1
  12. vb.net的UI设计
  13. 学会了 C 语言真的可以开发出很多东西吗?
  14. html怎么隐藏项目符号,CSS-如何隐藏侧边栏列表中的项目符号?
  15. 大家敏捷,才是真的敏捷——记敏捷培训
  16. 微软office认证课程
  17. Kali Linux系统正确安装指南教程(一)MAC安装kail+Vmware Fusion详细教程(吐血本人测试10次)
  18. 钻石特工java下载_联想i909——S141升级后的改变
  19. 在 Lenovo G360 笔记本上安装 Debian Squeeze AMD64
  20. VBS带你领略脚本语言的快乐!(实战篇—死循环)

热门文章

  1. 电信光猫贝尔RG201O-CA2破解详解 2013年4月
  2. 2008年最搞笑的10句话
  3. 基于javaweb+jsp的服装店门店信息管理系统(JavaWeb JSP MySQL Servlet SSM SpringBoot Bootstrap Ajax)
  4. 2022年高处安装、维护、拆除考试题库及在线模拟考试
  5. Android的屏幕大小和精度
  6. LeetCode每日练习
  7. Mac book pro wifi 频繁掉线,解决方案
  8. 同包同名的类的时候,使用哪个,哪个优先
  9. 计算机网络 鉴别释义,计算机网络 鉴别
  10. 怎么在python中添加文字_Python在图片中添加文字的两种方法