.net平台的RSA实现以及与Delphi之间的互操作性
.net平台下面的RSA算法实现是RSACryptoServiceProvider,如果安装了 Microsoft
Enhanced Cryptographic Provider,则 RSACryptoServiceProvider 支持长度从 384 位至
16384 位(增量为 8 位)的密钥。如果安装了 Microsoft Base Cryptographic Provider,则支持长度从 384
位至 512 位(增量为 8 位)的密钥。
目前该算法支持的填充Padding算法为PKCS#1
1.5和OAEPPadding,而签名算法目前仅支持SHA1withRSA算法,其他的好像没有提供,或许需要安装其他provider,目前第三方的provider可以使用Bouncy
Castle的C#实现http://www.bouncycastle.org/csharp/,使用Bouncy
Castle的包可以实现
RIPEMD128、RIPEMD160、RIPEMD256、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、MD2,MD4,MD5等HASH算法与RSA的集成签名算法。
为了更好的处理BigInteger运算的问题,在本文中用到了http://www.codeproject.com/csharp/biginteger.asp提供的BigInteger.cs用来处理大数运算的问题,用来验证的DLL实用delphi实现的,当然也可以用java来验证,效果相同,该DLL的代码在下面专题中作详细讲解。
具体源代码如下:
2using System.Text;
3using System.IO;
4using System.Net;
5using System.Xml;
6using System.Runtime.InteropServices;
7using System;
8using System.Security;
9using System.Security.Cryptography;
10/*
11 RSA Keyinfo:
12 ---------------------------------------------------------------------
13 可以采用java或者.net生成下面参数信息
14 加密位:1024bits
15 >>>PrivateKey:
16 modulus:123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929
17 public exponent:65537
18 private exponent:102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233
19 prime p:12794390226544301614076650435602993036558056678553112540698297249963365434628505393116653422818365344228379828231764392521731584684435248093787027949139091
20 prime q:9645694015283940797244851561543569992525098416055322825220116046655435860727361740896753161534492415500799272063647633894112205918420307541634544631799219
21 prime exponent p:1529969882744521289493243655703200580244831014386083326692594344385048063096931454992679141166478923397741927672190328275520857365639547725880173612423563
22 prime exponent q:769453717928871362558494956494038236735297839680443531596667023084892788499361386413907037681040120057954721673997128797449053397950796768659923391901465
23 crt coefficient:12583540851660819630796910273258143748946857763306703439274571717196507402536398234616014735603915981141807543055250658251670340810611251684169356826070785
24 >>>PublicKey:
25 modulus:123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929
26 public exponent:65537
27 */
28
29public class RSATest
30{
31 [DllImport("cmipcrypt.dll")]
32 public static extern String Cmip_Encrypt(String text,String exp,String module);
33
34 [DllImport("cmipcrypt.dll")]
35 public static extern String Cmip_Decrypt(String etext,String d,String module);
36
37 [DllImport("cmipcrypt.dll")]
38 public static extern String Cmip_SignData(String text,String d,String module,String alg);
39
40 [DllImport("cmipcrypt.dll")]
41 public static extern String Cmip_VerifyData(String text,String signtext,String r,String module);
42
43 [DllImport("cmipcrypt.dll")]
44 public static extern String Cmip_ComputeHash(String text,String alg);
45
46 private String p,q,e,n,d,dp,dq,crt;
47 private RSAParameters param;
48
49 public void init(){
50 p="12794390226544301614076650435602993036558056678553112540698297249963365434628505393116653422818365344228379828231764392521731584684435248093787027949139091";
51 q="9645694015283940797244851561543569992525098416055322825220116046655435860727361740896753161534492415500799272063647633894112205918420307541634544631799219";
52 e="65537";
53 n="123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929";
54 d="102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233";
55 dp="1529969882744521289493243655703200580244831014386083326692594344385048063096931454992679141166478923397741927672190328275520857365639547725880173612423563";
56 dq="769453717928871362558494956494038236735297839680443531596667023084892788499361386413907037681040120057954721673997128797449053397950796768659923391901465";
57 crt="12583540851660819630796910273258143748946857763306703439274571717196507402536398234616014735603915981141807543055250658251670340810611251684169356826070785";
58
59 param=new RSAParameters();
60 byte[] bdata=GetBytes(e);
61 param.Exponent=bdata;
62 param.P=GetBytes(p);
63 param.Q=GetBytes(q);
64 param.Modulus=GetBytes(n);
65 param.D=GetBytes(d);
66 param.DP=GetBytes(dp);
67 param.DQ=GetBytes(dq);
68 param.InverseQ=GetBytes(crt);
69 }
70
71 public static void Main(String[] args)
72 {
73 if(args.Length<2){
74 Console.WriteLine("\nRSATest.exe [text明文] [hash算法]。");
75 return;
76 }
77 RSATest rsa=new RSATest();
78 rsa.init();
79 rsa.DelphiDllTest(args[0],args[1]);
80 rsa.DotnetRSATest(args[0],args[1]);
81 rsa.InteropTest(args[0],args[1]);
82
83
84
85 }
86
87 public void DelphiDllTest(String text,String alg){
88 String res=Cmip_Encrypt(text,e,n);
89 Console.WriteLine("=====================Dll调用RSA测试=====================");
90 Console.WriteLine("\n1.明文:"+text);
91 //加密
92 Console.WriteLine("\n2.RSA加密:"+res);
93 res=Cmip_Decrypt(res,d,n);
94 Console.WriteLine("\n3.RSA解密:"+res);
95 //签名
96 String signdata=Cmip_SignData(text,d,n,alg);
97 Console.WriteLine("\n4.对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为:\n"+signdata);
98 Console.WriteLine("\n5.RSA验证签名:"+Cmip_VerifyData(text,signdata,e,n));
99
100 Console.WriteLine("\n6.采用HASH算法"+alg+"计算明文的结果:"+Cmip_ComputeHash(text,alg));
101 }
102 //.net只实现了SHA1的rsa签名算法
103 public void DotnetRSATest(String text,String alg){
104 Console.WriteLine("\n\n\n=========.net RSACryptoServiceProvider调用RSA测试=========");
105
106 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
107 rsa.ImportParameters(param);
108 RSAParameters param1=rsa.ExportParameters(true);
109
110 Console.WriteLine("1.明文:"+text);
111 byte[] data=Encoding.Default.GetBytes(text);
112 byte[] endata=rsa.Encrypt(data,false);
113 Console.WriteLine("\n2.publicKey加密后的数据:"+Convert.ToBase64String(endata));
114 byte[] dedata=rsa.Decrypt(endata,false);
115 Console.WriteLine("\n3.privateKey解密后的数据:"+Encoding.Default.GetString(dedata));
116 //签名
117 HashAlgorithm hashalg=null;
118 switch(alg.ToUpper()){
119 case "MD5":
120 hashalg=new MD5CryptoServiceProvider();
121 break;
122 case "SHA1":
123 hashalg=new SHA1CryptoServiceProvider (); ;
124 break;
125 case "SHA256":
126 hashalg=new SHA256Managed();
127 break;
128 case "SHA384":
129 hashalg=new SHA384Managed();
130 break;
131 case "SHA512":
132 hashalg=new SHA512Managed();
133 break;
134 default:
135 throw new Exception("不支持的HASH算法:"+alg);
136 }
137 try{
138 byte[] signdata=rsa.SignData(data,hashalg);
139 Console.WriteLine("\n4.对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为:\n"+Convert.ToBase64String(signdata));
140 Console.WriteLine("\n5.RSA验证签名:"+rsa.VerifyData(data,hashalg,signdata));
141 }catch(CryptographicException ex){
142 Console.WriteLine("\n===================================");
143 Console.WriteLine("!!!指定的HASH算法在.net中可能未实现!:"+ex.Message+"\n.net可用算法"+rsa.SignatureAlgorithm);
144 Console.WriteLine("===================================");
145 }
146 byte[] hash=hashalg.ComputeHash(data);
147 Console.WriteLine("\n6.采用HASH算法"+alg+"计算明文的结果:"+ConvByteArrayToHex(hash));
148
149
150 String res=Cmip_Decrypt(Convert.ToBase64String(endata),d,n);
151 Console.WriteLine("\n"+res);
152 Console.WriteLine(Encoding.Default.ToString());
153
154 }
155 //dll加密,.net解密
156 //dll签名,.net验证
157 public void InteropTest(String text,String alg){
158 String res=Cmip_Encrypt(text,e,n);
159 Console.WriteLine("\n=====================跨语言平台调用RSA测试=====================");
160 Console.WriteLine("\n1.明文:"+text);
161 //加密
162 Console.WriteLine("\n2.DLL RSA加密:"+res);
163 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
164 rsa.ImportParameters(param);
165 byte[] txdata=rsa.Decrypt(Convert.FromBase64String(res),false);
166
167 Console.WriteLine("\n3.RSACryptoServiceProvider RSA解密:"+Encoding.Default.GetString(txdata));
168 //dll签名,.net验证
169 String signdata=Cmip_SignData(text,d,n,alg);
170 Console.WriteLine("\n4.DLL 对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为:\n"+signdata);
171 //签名
172 HashAlgorithm hashalg=null;
173 switch(alg.ToUpper()){
174 case "MD5":
175 hashalg=new MD5CryptoServiceProvider();
176 break;
177 case "SHA1":
178 hashalg=new SHA1CryptoServiceProvider (); ;
179 break;
180 case "SHA256":
181 hashalg=new SHA256Managed();
182 break;
183 case "SHA384":
184 hashalg=new SHA384Managed();
185 break;
186 case "SHA512":
187 hashalg=new SHA512Managed();
188 break;
189 default:
190 throw new Exception("不支持的HASH算法:"+alg);
191 }
192 try{
193 Console.WriteLine("\n5.RSACryptoServiceProvider RSA验证签名:"+rsa.VerifyData(Encoding.Default.GetBytes(text),hashalg,Convert.FromBase64String(signdata)));
194 }catch(CryptographicException ex){
195 Console.WriteLine("\n===================================");
196 Console.WriteLine("!!!指定的HASH算法在.net中可能未实现!:"+ex.Message+"\n.net可用算法"+rsa.SignatureAlgorithm);
197 Console.WriteLine("===================================");
198 }
199 }
200
201 public static byte[] GetBytes(String num){
202 BigInteger n=new BigInteger(num,10);
203 String s=n.ToString(2);
204 if(s.Length%8>0){
205 s=new String(‘0‘,8-s.Length%8)+s;
206 }
207 byte[] data=new byte[s.Length/8];
208 String ocetstr;
209 for(int i=0;i<data.Length;i++){
210 ocetstr=s.Substring(8*i,8);
211 data[i]=Convert.ToByte(ocetstr , 2 ) ;
212 }
213 return data;
214 }
215
216 public String ConvByteArrayToHex(byte[] data){
217 String s="";
218 for(int i=0;i<data.Length;i++){
219 s+=Convert.ToString(data[i],16);
220 }
221 return s.ToUpper();
222 }
223
224
225}
运行结果如下:
d:\>rsatest hello加密
sha1 1.明文:hello加密 2.RSA加密:A/0ZWckK9C6JyTk8NmwESVSI/N8OyQ7nYBEK8cpzo30nHj+Pb0WfvQ+lFa38Xk3cd+d8ueysTSc7tqr4Wjk831d0MexAC2yJ4SkqLWfKnhuU0OxF6d4s8UpegvuMBy1KWpzovbFGa3HUGRmMVbu4GqPDdzkvFmfWzGArXXiDpVw= 3.RSA解密:hello加密 4.对明文采用sha1withRSA的签名算法,签名数据为: 5.RSA验证签名:true 6.采用HASH算法sha1计算明文的结果:C3F118FF24E166AC977EC9C3D69A5AF8B7C78F8B =========.net RSACryptoServiceProvider调用RSA测试========= 1.明文:hello加密 2.publicKey加密后的数据:NrW/Uwjd72SduBgQkOFjjtEibTX/+WOCV0/oIFMiEln5uhLZ5OaH6cyWPEXBEwjZIiUY78dmdk8BW6SmiDArNwFePf/tM7KCAcSU9Zz3PGl07ZDmvT1P8F24caKaX9+fGwy72mOtoBhFnKh18oOjq4wZ06e1g8IQQQco9W+kHgU= 3.privateKey解密后的数据:hello加密 4.对明文采用sha1withRSA的签名算法,签名数据为: 5.RSA验证签名:True 6.采用HASH算法sha1计算明文的结果:C3F118FF24E166AC977EC9C3D69A5AF8B7C78F8B hello加密 System.Text.DBCSCodePageEncoding =====================跨语言平台调用RSA测试===================== 1.明文:hello加密 2.DLL RSA加密:P/AP7Iwv7pYxh+T1a/PZ4UBCZABu7zPpNt65W5ncNfo8eVQbH8jlH/Jv+fGa0x4CCmRUaTA0O1HeO4LowRpFyPJkwLxQAsMedvfRcQ7Ro2Hggoz5uwRG6QZ2go0Io0KAOGhcV4efKHFG2xro4jYX2O2hWyHTeMldDQPxt98z2co= 3.RSACryptoServiceProvider RSA解密:hello加密 4.DLL
对明文采用sha1withRSA的签名算法,签名数据为: 5.RSACryptoServiceProvider RSA验证签名:True |
有关程序下载:
http://files.cnblogs.com/midea0978/rsa.net.rar
附注:对于这个RSA的跨平台技术,已经是07年研究的结果,后来就没怎么深入了,目前本人已经在一个项目中使用这方面该技术,应用在delphi,powerbuilder,J2EE复合环境中。对于这方面的详细源代码或者技术支持感兴趣的话,如能提供一定报酬的基础上,可使用站内消息联系博主转让!
当然如果免费使用的话,附件中的cmipcrypt.dll是没有任何限制,随便使用。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。