李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java实现RSA加密与解密
Leefs
2020-02-29 AM
6201℃
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://www.lilinchao.com/archives/659.html
上一篇
【转载】Java阻塞队列--BlockingQueue
下一篇
LeetCode-15三数之和
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
35
其它
25
GO
48
NLP
8
标签云
SQL练习题
JVM
Redis
Git
国产数据库改造
Flume
并发编程
机器学习
递归
Elastisearch
数据结构
Kibana
Spark SQL
设计模式
VUE
FileBeat
MyBatis-Plus
HDFS
数据结构和算法
序列化和反序列化
Spark Streaming
MySQL
二叉树
哈希表
Eclipse
SpringCloudAlibaba
DataWarehouse
Elasticsearch
LeetCode刷题
NIO
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞