李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java实现RSA加密与解密
Leefs
2020-02-29 AM
4453℃
0条
# Java实现RSA加密与解密 ### 前言 之前没有做过关于RSA加解密的对接,今天做的时候踩到一些坑今天整理一下。 ### 踩坑记录 当拿到私钥以后先打开看一下头部的加密方式: ![Java实现RSA加密与解密01.png][1] 一般Java都是通过PKCS8的加密方式对文件进行解密的,网上找到的工具类也都是针对PKCS8进行解密,但是一般原始的文件都是通过PKCS1方式进行加密 如果可以接触到正式环境的Linux系统可以执行如下命令: **pkcs1私钥转pkcs8私钥:** ``` openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt ``` 如果接触Linux不能轻易修改可以使用如下工具类: ```java import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.KeyFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class Main { public static String pkcs1_public = "" + "MIGJAoGBAK3m6BabZZ2qQwjmIOBOZ1q9g9OnqGapuinLs3182ew2LAQT62iLReBC\n" + "NB64TRh/tU4iIIjx5bNRpNZ8IrcP92YVNuxMrdSCqXpC5gpGFKf1CfG0SrO+TPmO\n" + "/d1zexJq/yArc7HbYMFZRfks7BjnaQGJ5rCVEVyS/y+0I5hU+t37AgMBAAE=\n"; public static String pkcs1_private = "" + "MIICWwIBAAKBgQCt5ugWm2WdqkMI5iDgTmdavYPTp6hmqbopy7N9fNnsNiwEE+to\n" + "i0XgQjQeuE0Yf7VOIiCI8eWzUaTWfCK3D/dmFTbsTK3Ugql6QuYKRhSn9QnxtEqz\n" + "vkz5jv3dc3sSav8gK3Ox22DBWUX5LOwY52kBieawlRFckv8vtCOYVPrd+wIDAQAB\n" + "AoGAR7qukGSYjWflLo59kQfF6c+xyGOnOnFXsFWtO118JcpSbXwp5X1M3StxhBpQ\n" + "8oH6rre048ejD0vlyfJ5/zg+utZ0V2x5xM4DxBTyZifdujZGac9dzsfZ/CO6NS1s\n" + "HblrMTnm5EiousPH1lywmhGce7LVfMR76mVAFZTpHScHLAECQQDY+sL4hs8v578j\n" + "nhURLS5bwvih4wVbajPsN7oiswEsjCYymDO8IywL4l9Pkvfxd4d3dh6BhsYfB2W8\n" + "2ItBaWdBAkEAzSz0D2zJGC/x5DN5At1NnmxSpMfqo6e3L9vMHe7T5mepsRwPIobQ\n" + "DQrdBdCeBd30qVi1lw7NmMPKEflIxo2SOwJAbotLO+0Kr4BlPBM07nxTSwLJQ0jz\n" + "GMDB1U4K8dS6+2Qnrc0nRmmw7hkVr+fTlFzuUmmGXz03wOU26wBz6g52QQJASUVA\n" + "czG6LrUQgRoQoQE+8tBkQwxRstf2B1VK83WSnrluVB1dGktiiQXUIHt7s0SsVr2j\n" + "O6rBqUhiJUEMyDtOeQJAb5DnL8q5FbPkZg82LilKBtMyI5iGYnXGkz9adp4Kgpf0\n" + "V5dXr1QJl3rdurgz5BbZjhrxU54GTFnm/izIoaAU2g==\n"; public static String pkcs8_public = "" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt5ugWm2WdqkMI5iDgTmdavYPT\n" + "p6hmqbopy7N9fNnsNiwEE+toi0XgQjQeuE0Yf7VOIiCI8eWzUaTWfCK3D/dmFTbs\n" + "TK3Ugql6QuYKRhSn9QnxtEqzvkz5jv3dc3sSav8gK3Ox22DBWUX5LOwY52kBieaw\n" + "lRFckv8vtCOYVPrd+wIDAQAB\n"; public static String pkcs8_private = "" + "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAK3m6BabZZ2qQwjm\n" + "IOBOZ1q9g9OnqGapuinLs3182ew2LAQT62iLReBCNB64TRh/tU4iIIjx5bNRpNZ8\n" + "IrcP92YVNuxMrdSCqXpC5gpGFKf1CfG0SrO+TPmO/d1zexJq/yArc7HbYMFZRfks\n" + "7BjnaQGJ5rCVEVyS/y+0I5hU+t37AgMBAAECgYBHuq6QZJiNZ+Uujn2RB8Xpz7HI\n" + "Y6c6cVewVa07XXwlylJtfCnlfUzdK3GEGlDygfqut7Tjx6MPS+XJ8nn/OD661nRX\n" + "bHnEzgPEFPJmJ926NkZpz13Ox9n8I7o1LWwduWsxOebkSKi6w8fWXLCaEZx7stV8\n" + "xHvqZUAVlOkdJwcsAQJBANj6wviGzy/nvyOeFREtLlvC+KHjBVtqM+w3uiKzASyM\n" + "JjKYM7wjLAviX0+S9/F3h3d2HoGGxh8HZbzYi0FpZ0ECQQDNLPQPbMkYL/HkM3kC\n" + "3U2ebFKkx+qjp7cv28wd7tPmZ6mxHA8ihtANCt0F0J4F3fSpWLWXDs2Yw8oR+UjG\n" + "jZI7AkBui0s77QqvgGU8EzTufFNLAslDSPMYwMHVTgrx1Lr7ZCetzSdGabDuGRWv\n" + "59OUXO5SaYZfPTfA5TbrAHPqDnZBAkBJRUBzMboutRCBGhChAT7y0GRDDFGy1/YH\n" + "VUrzdZKeuW5UHV0aS2KJBdQge3uzRKxWvaM7qsGpSGIlQQzIO055AkBvkOcvyrkV\n" + "s+RmDzYuKUoG0zIjmIZidcaTP1p2ngqCl/RXl1evVAmXet26uDPkFtmOGvFTngZM\n" + "Web+LMihoBTa\n"; public static void main(String[] args) throws Exception { System.out.println(private_decrypt(public_encrypt("PKCS#8公钥加密,PKCS#8私钥解密", pkcs8_public), pkcs8_private)); System.out.println(public_decrypt(private_encrypt("PKCS#8私钥加密,PKCS#8公钥解密", pkcs8_private), pkcs8_public)); //System.out.println(private_decrypt(public_encrypt("PKCS#8公钥加密,PKCS#1私钥解密",pkcs8_public),pkcs1_private)); //System.out.println(private_decrypt(public_encrypt("PKCS#1公钥加密,PKCS#8私钥解密",pkcs1_public),pkcs8_private)); //System.out.println(private_decrypt(public_encrypt("PKCS#1公钥加密,PKCS#1私钥解密",pkcs1_public),pkcs1_private)); //System.out.println(public_decrypt(private_encrypt("PKCS#1私钥加密,PKCS#8公钥解密",pkcs1_private),pkcs8_public)); //System.out.println(public_decrypt(private_encrypt("PKCS#8私钥加密,PKCS#1公钥解密",pkcs8_private),pkcs1_public)); //System.out.println(public_decrypt(private_encrypt("PKCS#1私钥加密,PKCS#1公钥解密",pkcs1_private),pkcs1_public)); } public static String public_encrypt(String str, String publicKey) throws Exception { byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; } public static String private_encrypt(String str, String privateKey) throws Exception { byte[] decoded = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, priKey); String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; } public static String private_decrypt(String str, String privateKey) throws Exception { byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8")); byte[] decoded = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; } public static String public_decrypt(String str, String publicKey) throws Exception { byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8")); byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, pubKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; } } ``` 工具类中包含了PKCS#1和PKCS#8之间各种情况的相互转换。相信总有一个满足你的需求。 ### 今天RSA密钥解密又碰见一个坑 通过上面的工具类调用PKCS1私钥解密方法报如下错误 ```java Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217) at java.security.KeyFactory.generatePrivate(KeyFactory.java:372) at com.mmit.common.RSAUtils.private_decrypt(RSAUtils.java:112) at com.mmit.common.RSAUtils.main(RSAUtils.java:82) Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351) at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356) at sun.security.rsa.RSAPrivateCrtKeyImpl.
(RSAPrivateCrtKeyImpl.java:91) at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316) at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213) ... 3 more ``` 百度了上都是说**问题的原因是:rsa私钥的格式不是pksc8格式**,然而并不是。 在私钥解密时加上如下代码: ```java java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider() ); ``` 问题解决方法 **附完整代码** ```java public static String private_decrypt(String str, String privateKey) throws Exception { java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider() ); byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8")); byte[] decoded = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; } ``` [1]: https://lilinchao.com/usr/uploads/2020/03/2402510912.png
标签:
Java工具类
,
RSA加解密
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/659.html
上一篇
【转载】Java阻塞队列--BlockingQueue
下一篇
LeetCode-15三数之和
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
国产数据库改造
Livy
ClickHouse
SpringBoot
Thymeleaf
Shiro
Stream流
Elasticsearch
Spark SQL
Http
Java阻塞队列
随笔
JavaScript
数学
DataX
设计模式
线程池
人工智能
序列化和反序列化
正则表达式
NIO
Ubuntu
JavaWEB项目搭建
Typora
VUE
MySQL
ajax
Azkaban
JavaSE
SpringCloudAlibaba
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭