非对称密钥RSA算法加解密在C#和Java之间交互的问题,这两天看了很多其他人写的文章,碰到了几个问题,最终解决问题。

参考地址:http://xw-z1985.iteye.com/blog/1837376

需求目的:完成c#请求端RSA加密(签名)问题,客户端采用C#开发,服务器端采用Java开发。服务器端给客户端提供私钥,进行数据加密(签名),客户端加密(签名)后提数据提交给服务器,服务器用公钥对数据解密,进行验证。

解决过程碰到的问题:

1.JAVA 需要的 RSA私钥 格式和 C# 需要的 RSA私钥 不一致。

JAVA 需要是 PKCS8格式私钥:

-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOwuOHH/OIRE+0if
mEPYGuhYRTyKdd6VLFIsNqy/SO5xZitHfA7xEymJKnpEUGgDJKr5zbFbytnWs5Jj
gen6TXkUh9LG/fhPGGHdUVB42pAHv5yzoyEaOnJxBAxd6UstoWTaEgbT6GUbzMr/
Az25zuxw7c+skAlnUETVE5GL3tD7AgMBAAECgYEAxdNZODMctb3J9OSo93rV3vPA
2prna87rVtDt4vg+MGsPtwSjZyiKcmoQCGWcK+MmHYgrwHkwihKKSv3KXZ9or3xQ
2wNZGuTHLymWEzqfEfVb0igvxbe85EGwsaN3qSK62CK8vok/Bi+fZVa3UNCn0WFs
lUS0qn+K3SECM9I1iwECQQD+2Pl2AJGQs2bRXSsnJk0FIwjpqdpGZFPlAUYaXkuT
MqpwefP/bwwiuWqq9QIt2vAAKgy5T16tpPBcGpT6cvxBAkEA7T+i1gVwrXcozTuT
9oCwkF2MGBaXkv3mN9H/Pfy/oIhTsgiDxX8t+0KapAEQogvCuAOq19JvGw5e91H2
g0suOwJAJOMnCIuAhl9RTJCdxGbo0wuFKL0rGPFAq28JxJtNeRrmTK16QcjDCuun
ouMf059TCdMMUG5Kl/u9xrcaRT4LgQJAZPiUYOnnzqvMHayhiGO0wXxOx2G2GMUe
Wdtx+fu7wqLCnB6rlj5OX4U1M1+QqKbAtHg7Gadhye4P1Mp5U9+HSQJBANLVzcCX
yAX2D12UPTPkhcNRaCRXFp3aJGMxI4iluUC+ukAdiapohqZ7vMQyWRq/tDyiwjir
qMcg/AJIuQWmPyc=
-----END PRIVATE KEY-----

C# 需要的是 PKCS1 格式私钥:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDsLjhx/ziERPtIn5hD2BroWEU8inXelSxSLDasv0jucWYrR3wO
8RMpiSp6RFBoAySq+c2xW8rZ1rOSY4Hp+k15FIfSxv34Txhh3VFQeNqQB7+cs6Mh
GjpycQQMXelLLaFk2hIG0+hlG8zK/wM9uc7scO3PrJAJZ1BE1RORi97Q+wIDAQAB
AoGBAMXTWTgzHLW9yfTkqPd61d7zwNqa52vO61bQ7eL4PjBrD7cEo2coinJqEAhl
nCvjJh2IK8B5MIoSikr9yl2faK98UNsDWRrkxy8plhM6nxH1W9IoL8W3vORBsLGj
d6kiutgivL6JPwYvn2VWt1DQp9FhbJVEtKp/it0hAjPSNYsBAkEA/tj5dgCRkLNm
0V0rJyZNBSMI6anaRmRT5QFGGl5LkzKqcHnz/28MIrlqqvUCLdrwACoMuU9eraTw
XBqU+nL8QQJBAO0/otYFcK13KM07k/aAsJBdjBgWl5L95jfR/z38v6CIU7IIg8V/
LftCmqQBEKILwrgDqtfSbxsOXvdR9oNLLjsCQCTjJwiLgIZfUUyQncRm6NMLhSi9
KxjxQKtvCcSbTXka5kytekHIwwrrp6LjH9OfUwnTDFBuSpf7vca3GkU+C4ECQGT4
lGDp586rzB2soYhjtMF8TsdhthjFHlnbcfn7u8Kiwpweq5Y+Tl+FNTNfkKimwLR4
OxmnYcnuD9TKeVPfh0kCQQDS1c3Al8gF9g9dlD0z5IXDUWgkVxad2iRjMSOIpblA
vrpAHYmqaIame7zEMlkav7Q8osI4q6jHIPwCSLkFpj8n
-----END RSA PRIVATE KEY-----

2.私钥格式之间的转换问题

转换工具:openssl工具:http://www.slproweb.com/products/Win32OpenSSL.html

转换参考地址: http://blog.csdn.net/hanzengyi/article/details/78029104

java 代码 , 注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN PRIVATE KEY-----)和尾(-----END PRIVATE KEY-----)以及换行符后的字符串

 1    /**
2 * @data: 待加密的字符串
3 * @privateKey: 私钥
4 */
5 public static String sign(byte[] data, String privateKey) throws Exception {
6
7 byte[] keyBytes = new BASE64Decoder().decodeBuffer(privateKey);
8 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
9
10 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
11
12 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
13
14 Signature signature = Signature.getInstance("SHA1withRSA");
15 signature.initSign(priKey);
16 signature.update(data);
17
18 return byte2hex(signature.sign());
19 }

c# 代码,注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN RSA PRIVATE KEY-----)和尾(-----END RSA PRIVATE KEY-----)以及换行符后的字符串

  1       /// <summary>
2      /// 签名
3      /// </summary>
4      /// <param name="data">待加密的字符串</param>
5      /// <param name="privateKey">私钥</param>
6      /// <returns></returns>
7      public static string Sign(string data, string privateKey)
8 {
9 RSACryptoServiceProvider rsaCsp = LoadCertificate(privateKey);
10 byte[] dataBytes = Encoding.UTF8.GetBytes(data);
11 byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
12 return Hex_2To16(signatureBytes);
13 }
14
15 private static RSACryptoServiceProvider LoadCertificate(string privateKey)
16 {
17 byte[] res = res = Convert.FromBase64String(privateKey);
18 try
19 {
20 RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);
21 return rsa;
22 }
23 catch (Exception ex)
24 {
25 }
26 return null;
27 }
28
29 private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
30 {
31 byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
32
33 // --------- Set up stream to decode the asn.1 encoded RSA private key ------
34 MemoryStream mem = new MemoryStream(privkey);
35 BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
36 byte bt = 0;
37 ushort twobytes = 0;
38 int elems = 0;
39 try
40 {
41 twobytes = binr.ReadUInt16();
42 if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
43 binr.ReadByte(); //advance 1 byte
44 else if (twobytes == 0x8230)
45 binr.ReadInt16(); //advance 2 bytes
46 else
47 return null;
48
49 twobytes = binr.ReadUInt16();
50 if (twobytes != 0x0102) //version number
51 return null;
52 bt = binr.ReadByte();
53 if (bt != 0x00)
54 return null;
55
56
57 //------ all private key components are Integer sequences ----
58 elems = GetIntegerSize(binr);
59 MODULUS = binr.ReadBytes(elems);
60
61 elems = GetIntegerSize(binr);
62 E = binr.ReadBytes(elems);
63
64 elems = GetIntegerSize(binr);
65 D = binr.ReadBytes(elems);
66
67 elems = GetIntegerSize(binr);
68 P = binr.ReadBytes(elems);
69
70 elems = GetIntegerSize(binr);
71 Q = binr.ReadBytes(elems);
72
73 elems = GetIntegerSize(binr);
74 DP = binr.ReadBytes(elems);
75
76 elems = GetIntegerSize(binr);
77 DQ = binr.ReadBytes(elems);
78
79 elems = GetIntegerSize(binr);
80 IQ = binr.ReadBytes(elems);
81
82
83 // ------- create RSACryptoServiceProvider instance and initialize with public key -----
84 CspParameters CspParameters = new CspParameters();
85 CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
86 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
87 RSAParameters RSAparams = new RSAParameters();
88 RSAparams.Modulus = MODULUS;
89 RSAparams.Exponent = E;
90 RSAparams.D = D;
91 RSAparams.P = P;
92 RSAparams.Q = Q;
93 RSAparams.DP = DP;
94 RSAparams.DQ = DQ;
95 RSAparams.InverseQ = IQ;
96 RSA.ImportParameters(RSAparams);
97 return RSA;
98 }
99 catch (Exception ex)
100 {
101 return null;
102 }
103 finally
104 {
105 binr.Close();
106 }
107 }
108
109 private static int GetIntegerSize(BinaryReader binr)
110 {
111 byte bt = 0;
112 byte lowbyte = 0x00;
113 byte highbyte = 0x00;
114 int count = 0;
115 bt = binr.ReadByte();
116 if (bt != 0x02) //expect integer
117 return 0;
118 bt = binr.ReadByte();
119
120 if (bt == 0x81)
121 count = binr.ReadByte(); // data size in next byte
122 else
123 if (bt == 0x82)
124 {
125 highbyte = binr.ReadByte(); // data size in next 2 bytes
126 lowbyte = binr.ReadByte();
127 byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
128 count = BitConverter.ToInt32(modint, 0);
129 }
130 else
131 {
132 count = bt; // we already have the data size
133 }
134
135 while (binr.ReadByte() == 0x00)
136 { //remove high order zeros in data
137 count -= 1;
138 }
139 binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
140 return count;
141 }
142
143
144 /// <summary>
145 /// 2进制转16进制
146 /// </summary>
147 public static String Hex_2To16(Byte[] bytes)
148 {
149 String hexString = String.Empty;
150 Int32 iLength = 65535;
151 if (bytes != null)
152 {
153 StringBuilder strB = new StringBuilder();
154
155 if (bytes.Length < iLength)
156 {
157 iLength = bytes.Length;
158 }
159
160 for (int i = 0; i < iLength; i++)
161 {
162 strB.Append(bytes[i].ToString("X2"));
163 }
164 hexString = strB.ToString();
165 }
166 return hexString;
167 }

JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)的更多相关文章

  1. Java前端Rsa公钥加密,后端Rsa私钥解密(目前还不支持中文加密解密,其他都行)

    Base64工具类,可以让rsa编码的乱码变成一串字符序列 package com.utils; import java.io.ByteArrayInputStream; import java.io ...

  2. java RSA加密解密实现(含分段加密)

    该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/50255 ...

  3. 浅谈IM软件业务知识——非对称加密,RSA算法,数字签名,公钥,私钥

    概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的.RSA就是取自他们三个人的名字. 算法基于一个数论:将两个大素数相乘很ea ...

  4. RSA加密、解密、公钥私钥生成

    有时项目中需要用到一些加密和解密工具,这里之前整理了一个demo,记录一下,方便查询 package com.test; import java.security.KeyFactory; import ...

  5. rsa公钥和私钥到底哪个才是用来加密,哪个用来解密?

    本文转自:91博客:原文地址:http://www.9191boke.com/138589019.html 公钥和私钥在一些银行系统.第三方支付系统SDK中经常会遇到,刚接触公钥私钥的朋友们估计很难区 ...

  6. 基于私钥加密公钥解密的RSA算法C#实现

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  7. JAVA中使用RSA通过秘钥文件对字符串进行加密解密

    技术交流群: 233513714 //字符串进行加密算法的名称 public static final String ALGORITHM = "RSA"; //字符串进行加密填充的 ...

  8. php/js/linux: js加密(rsa公钥加密) php解密(rsa私钥解密)

    php/js/linux: js加密(rsa公钥加密) php解密(rsa私钥解密) 一: js rsa 插件 https://github.com/UFO0001/WX_RSA 或者: https: ...

  9. Delphi RSA加解密【 (RSA公钥加密,私钥解密)、(RSA私钥加密,公钥解密)、MD5加密、SHA加密】

    作者QQ:(648437169) 点击下载➨delphi RSA加解密 [Delphi RSA加解密]支持 (RSA公钥加密,私钥解密).(RSA私钥加密,公钥解密).MD5加密.SHA1加密.SHA ...

随机推荐

  1. Windows平台下使用Beyond Compare作为GIT默认的比对与合并工具

    在Windows平台使用GUI习惯了,因此在CMD命令下反而感到不适 特别是在使用GIT时,尤其明显(这主要是GIT在工作中已经不可或缺) 使用GIT最常用的功能就是提交,添加,比较差异和合并分支,特 ...

  2. google test框架与eclipse插件

    1. https://github.com/google/googletest    (google的测试框架) 2. eclipse测试框架插件 https://github.com/xgsa/cd ...

  3. Python操作记录

    1.写入中文出错,需要执行 reload(sys) sys.setdefaultencoding('utf8') 2.json.dump中文写入为\xxxx ensure_ascii=False

  4. 离线LCA学习

    题目1 : 近期公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 上上回说到,小Hi和小Ho用很拙劣--或者说粗糙的手段山寨出了一个奇妙的站点,这个站点能 ...

  5. .NET Framework System.Array.Sort 数组类,加深对 IComparer、IComparable 以及泛型委托、匿名方法、Lambda 表达式的理解

    本文内容 自定义类 Array.Sort 参考资料 System.Array.Sort 有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对 IComparer.IComparable ...

  6. AWR - Load Profile 节

    AWR 报告的"Load profile"节,如下图所示,包含很多极为有用,却被经常忽视的信息.通常更倾向使用"instance efficiency percentag ...

  7. C#.NET常见问题(FAQ)-如何修改Form不能修改窗体大小

    把FormBorderSytle改一下就可以了,改成FixedSingle或者Fixed3D都可以   更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com ...

  8. phpstudy 开启apache反向代理

    vhosts.conf 1 2 3 4 5 6 7 8 9 10 11 <VirtualHost *:8080> ServerAdmin webmaster@dummy-host.exam ...

  9. 【树莓派】树莓派上面安装配置teamviewer

    访问树莓派桌面,的另一种方式,就是使用Teamviewer. 参考这篇文章做了实验:http://www.linuxdiyf.com/linux/16887.html,对其中部分进行了件要整理和总结. ...

  10. 微软BI 之SSRS 系列 - 在 Cube 中通过 MDX 查询实现基于父子递归关系的汇总报表

    之前我写了一篇在 SSRS 开发中处理这种父子关系的汇总与聚合的文章 (SSRS 系列 - 使用分组 Group 属性实现基于父子递归关系的汇总报表),示例中的查询是基于 SQL Server 关系型 ...