JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)
非对称密钥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私钥 加密(签名)的更多相关文章
- Java前端Rsa公钥加密,后端Rsa私钥解密(目前还不支持中文加密解密,其他都行)
Base64工具类,可以让rsa编码的乱码变成一串字符序列 package com.utils; import java.io.ByteArrayInputStream; import java.io ...
- java RSA加密解密实现(含分段加密)
该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/50255 ...
- 浅谈IM软件业务知识——非对称加密,RSA算法,数字签名,公钥,私钥
概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的.RSA就是取自他们三个人的名字. 算法基于一个数论:将两个大素数相乘很ea ...
- RSA加密、解密、公钥私钥生成
有时项目中需要用到一些加密和解密工具,这里之前整理了一个demo,记录一下,方便查询 package com.test; import java.security.KeyFactory; import ...
- rsa公钥和私钥到底哪个才是用来加密,哪个用来解密?
本文转自:91博客:原文地址:http://www.9191boke.com/138589019.html 公钥和私钥在一些银行系统.第三方支付系统SDK中经常会遇到,刚接触公钥私钥的朋友们估计很难区 ...
- 基于私钥加密公钥解密的RSA算法C#实现
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...
- JAVA中使用RSA通过秘钥文件对字符串进行加密解密
技术交流群: 233513714 //字符串进行加密算法的名称 public static final String ALGORITHM = "RSA"; //字符串进行加密填充的 ...
- php/js/linux: js加密(rsa公钥加密) php解密(rsa私钥解密)
php/js/linux: js加密(rsa公钥加密) php解密(rsa私钥解密) 一: js rsa 插件 https://github.com/UFO0001/WX_RSA 或者: https: ...
- Delphi RSA加解密【 (RSA公钥加密,私钥解密)、(RSA私钥加密,公钥解密)、MD5加密、SHA加密】
作者QQ:(648437169) 点击下载➨delphi RSA加解密 [Delphi RSA加解密]支持 (RSA公钥加密,私钥解密).(RSA私钥加密,公钥解密).MD5加密.SHA1加密.SHA ...
随机推荐
- 可以在任何时候attach一个shader到program对象
可以在任何时候attach一个shader到program对象,不一定非要在指定source和编译以后,具体的描述如下: Once you have a program object create ...
- js 前加分号和感叹号的含义
;!function(){}(); ;!有什么用? 从语法上来开.Javascript中分号表示语句结束,在开头加上.可能是为了压缩的时候和别的方法切割一下,表示一个新的语句開始.所以,假设在一个单 ...
- 在CentOS 7上安装Nginx服务器
下面我就我在CentOS上安装Nginx经验做简单的记录,以备后查. 1.下载nginx-release包 以CentOS 7为例,下载nginx软件包:http://nginx.org/packag ...
- Timer 与 TimerTask 示例
, 1000);// 1秒后执行 然后每隔1秒 执行一次 ); ); timer.cancel();//停止任务(程序停止) } } /** * 启动刷新滚动数据的定时器 */public void ...
- 解决IE6兼容性问题的十一大技巧
10要点解决IE6兼容性问题 1.使用声明 你必须经常在html网页头部放置一个声明,推荐使用严格的标准.例如 <!DOCTYPEHTMLPUBLIC“-//W3C//DTDHTML4.01// ...
- 自定义控件之万能Repeater源码
using System.ComponentModel; using System.Web.UI; [assembly: TagPrefix("Jinlong.Control", ...
- 微信小程序 - 上传图片(组件)
更新日期: 2019/3/14:首次发布,更新了2018/12/30的UI以及反馈信息获取方式,具体请下载:demo. 2019/3/20:感谢544429676@qq.com指出的现存bug,已修复 ...
- SQLServer中查询表结构(表主键 、列说明、列数据类型、所有表名)的Sql语句
SQLServer中查询表结构(表主键 .列说明.列数据类型.所有表名)的Sql语句 1.查询数据库中的所有表名称: SELECT name FROM SysObjects Where XType=' ...
- 008-Go 关于字符串拼接
如果是少量小文本拼接,用 “+” 如果是大量小文本拼接,用 strings.Join 如果是大量大文本拼接,用 bytes.Buffer package main import( "fmt& ...
- h5画图表
折线: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&q ...