java与rsa加密互通
最近遇到⼀个项⽬需要做单点,⽤户⽅是采⽤java rsa公钥加密传递信息的,我这边是使⽤私钥解密。⽽对⽅提供的解密源码是java版本的,并且也没有做过与平台的单
点对接。
于是在⽹上到了如下版本的c# 版本rsa私钥解密⽅法
1///<summary>
2/// RSA的解密函数
3///</summary>
4///<param name="xmlPrivateKey">私钥</param>
5///<param name="decryptString">待解密的字符串</param>
6///<returns></returns>
7public string RSADecrypt(string xmlPrivateKey, string decryptString)
8        {
9byte[] PlainTextBArray;//解密前字节流
10byte[] DypherTextBArray;//解密后字节流
11string Result = "";
12                System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
13                rsa.FromXmlString(xmlPrivateKey);
14                PlainTextBArray = Convert.FromBase64String(decryptString);
15                DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
16                Result = Encoding.UTF8.GetString(DypherTextBArray);
17return Result;
18        }
拿过来之后把私钥和带解密字符串传⼊,发现报错,于是研究发现,c#的rsa解密私钥是xml格式的,⽽对⽅提供的是base64字符串,所以需要先把私钥转成xml格式,
转换⽆法在c#中进⾏,需要打开在java下⾯转换,可以下个exclipse把如下代码复制进去就⾏。
1package com;
2
3import java.security.KeyFactory;
4import java.security.PublicKey;
5import java.security.interfaces.RSAPrivateCrtKey;
6import java.security.interfaces.RSAPublicKey;
7import java.security.spec.PKCS8EncodedKeySpec;
8import java.security.spec.X509EncodedKeySpec;
9//import org.castor.util.Base64Decoder;
10//import org.castor.util.Base64Encoder;
11
12public class test {
13
14public static void main(String[] args)
15 {
16 String tes="MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAL8z2QlXCL6w7rvY0Gbl8ARtQSXY+pEW5hlUHlmspqHt4k8/SkoF796gDqk4yyOcoWhkZWLPPugK35Mn7V+m5Jyfu8C0gVKOfWOA8A0T4hxV2ThAoMUq7QtB2K  17byte[] temp=b64decode(tes);
18 String ver=getRSAPrivateKeyAsNetFormat(temp);//转换私钥
19
20 String tes1="MIGfMA0GCSqGSIb4DQEBAQUAA4GNADCBiQKBgQC/M9kJVwi+sO672NBm5fAE
bUEl2PqRFuYZVB5ZrKah7eJPP0pKBe/eoA6pOMsjnKFoZGVizz7oCt+TJ+1fpuScn7vAtIFSjn1jgPANE+IcVdk4QKDFKu0LQdiurPQKLpq8Q3wJ  21byte[] temp1=b64decode(tes1);
22 String ver1=getRSAPublicKeyAsNetFormat(temp1);//转换公钥
23//String temp2= encodePublicKeyToXml(temp1);
24
25 }
26
27private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivkey) {
28try {
29 StringBuffer buff = new StringBuffer(1024);
30
31 PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
32 encodedPrivkey);
33 KeyFactory keyFactory = Instance("RSA");
34 RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
35 .generatePrivate(pvkKeySpec);
36
37 buff.append("<RSAKeyValue>");
38 buff.append("<Modulus>"
39 + b64encode(Modulus().toByteArray()))
40 + "</Modulus>");
41
42 buff.append("<Exponent>"
43 + b64encode(PublicExponent()
44 .toByteArray())) + "</Exponent>");
45
46 buff.append("<P>"
47 + b64encode(PrimeP().toByteArray()))
48 + "</P>");
49
50 buff.append("<Q>"
51 + b64encode(PrimeQ().toByteArray()))
52 + "</Q>");
53
54 buff.append("<DP>"
55 + b64encode(PrimeExponentP()
56 .toByteArray())) + "</DP>");
57
58 buff.append("<DQ>"
59 + b64encode(PrimeExponentQ()
60 .toByteArray())) + "</DQ>");
61
62 buff.append("<InverseQ>"
63 + b64encode(CrtCoefficient()
64 .toByteArray())) + "</InverseQ>");
65
66 buff.append("<D>"
67 + b64encode(PrivateExponent()
68 .toByteArray())) + "</D>");
69 buff.append("</RSAKeyValue>");
70
String().replaceAll("[ \t\n\r]", "");
72 } catch (Exception e) {
println(e);
74return null;
75 }
java源代码加密76 }
77
78private static String getRSAPublicKeyAsNetFormat(byte[] encodedPrivkey) {
79try {
80 StringBuffer buff = new StringBuffer(1024);
81
82 PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(encodedPrivkey);
83 KeyFactory keyFactory = Instance("RSA");
84 RSAPublicKey pukKey=(RSAPublicKey) atePublic(new X509EncodedKeySpec(encodedPrivkey));
85// RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) atePrivate(pvkKeySpec);
86//PublicKey publicKey =Instance("RSA").generatePublic(pvkKeySpec);
87 buff.append("<RSAKeyValue>");
88 buff.append("<Modulus>"
89 + b64encode(Modulus().toByteArray()))
90 + "</Modulus>");
91 buff.append("<Exponent>"
92 + b64encode(PublicExponent()
93 .toByteArray())) + "</Exponent>");
94 buff.append("</RSAKeyValue>");
String().replaceAll("[ \t\n\r]", "");
96 } catch (Exception e) {
println(e);
98return null;
99 }
100 }
101public static String encodePublicKeyToXml(PublicKey key) {
102if (!RSAPublicKey.class.isInstance(key)) {
103return null;
104 }
105 RSAPublicKey pubKey = (RSAPublicKey) key;
106 StringBuilder sb = new StringBuilder();
107 sb.append("<RSAKeyValue>");
108 sb.append("<Modulus>")
109 .Modulus().toByteArray()))
110 .append("</Modulus>");
111 sb.append("<Exponent>")
112 .PublicExponent()
113 .toByteArray())).append("</Exponent>");
114 sb.append("</RSAKeyValue>");
String();
116 }
117
118private static byte[] removeMSZero(byte[] data) {
119byte[] data1;
120int len = data.length;
121if (data[0] == 0) {
122 data1 = new byte[data.length - 1];
123 System.arraycopy(data, 1, data1, 0, len - 1);
124 } else
125 data1 = data;
126return data1;
127 }
128private static String b64encode(byte[] data) {
129
130 String b64str = new de(data));
131return b64str;
132 }
133
134private static byte[] b64decode(String data) {
135byte[] decodeData = Base64.decode(data);
136return decodeData;
137 }
138 }
现在拿到c#的私钥了,发现解密还是报错,⼜看了下,发现⽤户给的加密⽂本是16进制⽂本,并不是base64⽂本,于是写了个16进制转字节的⽅法供调⽤。16进制⽂本转字节流⽅法如下
1///<summary>
2/// 16进制⽂本转字节流
3///</summary>
4///<param name="src">16进制⽂本</param>
5///<returns></returns>
6public byte[] hexStr2ByteArr(string src)
7        {
8int l = src.Length / 2;//2个16进制⽂本等于⼀个字节,所以字节数组长度是16进制⽂本长度的⼀半
9            String str;
10byte[] ret = new byte[l];
11
12for (int i = 0; i < l; i++)
13            {
14                str = src.Substring(i * 2, 2);
15                ret[i] = Convert.ToByte(str, 16);
16            }
17return ret;
18        }
然后下⼀个坑⼜出来了,rsa解密⼀次只能128个字节,所以⼜写了个循环的⽅法,每次解密128个字节数组,最终再拼接起来,最终代码如下:
1///<summary>
2/// RSA的解密函数
3///</summary>
4///<param name="xmlPrivateKey">私钥</param>
5///<param name="decryptString">待解密的字符串</param>
6///<returns></returns>
7public string RSADecrypt(string xmlPrivateKey, string decryptString)
8        {
9try
10            {
11byte[] PlainTextBArray;
12byte[] DypherTextBArray;
13string Result = "";
14                System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
15                rsa.FromXmlString(xmlPrivateKey);
16                PlainTextBArray = hexStr2ByteArr(decryptString);
17var outlength = PlainTextBArray.Length;
18var i = 0;
19while (true) {
20if (outlength > 128)
21                    {
22var aa = new byte[128];
23                        Array.Copy(PlainTextBArray, i, aa, 0, 128);
24                        DypherTextBArray = rsa.Decrypt(aa, false);
25                        Result = Result + Encoding.UTF8.GetString(DypherTextBArray);
26                        outlength = outlength - 128;
27                        i = i + 128;
28                    }
29else {
30var aa = new byte[outlength];
31                        Array.Copy(PlainTextBArray, i, aa, 0, outlength);
32                        DypherTextBArray = rsa.Decrypt(aa, false);
33                        Result = Result + Encoding.UTF8.GetString(DypherTextBArray);
34break;
35                    }
36                }
37return Result;
38            }
39catch (Exception ex)
40            {
41throw ex;
42            }
43        }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。