.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的代码在下面专题中作详细讲解。
具体源代码如下:
using System.Text.RegularExpressions;2
using System.Text;3
using System.IO;4
using System.Net;5
using System.Xml;6
using System.Runtime.InteropServices;7
using System;8
using System.Security;9
using System.Security.Cryptography;10
/*11
RSA Keyinfo:12
---------------------------------------------------------------------13
可以采用java或者.net生成下面参数信息14
加密位:1024bits15
>>>PrivateKey:16
modulus:12341077323738571357244071284001940587825760021390635177513440276652478560577635363551587943837596930333334069122432321737979161994646410028785426493366091937848500029925705403955588747761083182940914459260308678439767569093424642266668902231258931749300233607077571403095573743531665999402675695675341616992917
public exponent:6553718
private exponent:10229967296175009957026434175728053227554240183744566377063264361649488842668120584712506929473752091754103890003284531039526617857411246642717809476762839139837892495378704365932214849816901798973095380380389098929562502819315348055224721018398195994284434536211847951373963295209186536009555134535047461423319
prime p:1279439022654430161407665043560299303655805667855311254069829724996336543462850539311665342281836534422837982823176439252173158468443524809378702794913909120
prime q:964569401528394079724485156154356999252509841605532282522011604665543586072736174089675316153449241550079927206364763389411220591842030754163454463179921921
prime exponent p:152996988274452128949324365570320058024483101438608332669259434438504806309693145499267914116647892339774192767219032827552085736563954772588017361242356322
prime exponent q:76945371792887136255849495649403823673529783968044353159666702308489278849936138641390703768104012005795472167399712879744905339795079676865992339190146523
crt coefficient:1258354085166081963079691027325814374894685776330670343927457171719650740253639823461601473560391598114180754305525065825167034081061125168416935682607078524
>>>PublicKey:25
modulus:12341077323738571357244071284001940587825760021390635177513440276652478560577635363551587943837596930333334069122432321737979161994646410028785426493366091937848500029925705403955588747761083182940914459260308678439767569093424642266668902231258931749300233607077571403095573743531665999402675695675341616992926
public exponent:6553727
*/28

29
public class RSATest30
{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 |
有关程序下载:
https://files.cnblogs.com/midea0978/rsa.net.rar
附注:对于这个RSA的跨平台技术,已经是07年研究的结果,后来就没怎么深入了,目前本人已经在一个项目中使用这方面该技术,应用在delphi,powerbuilder,J2EE复合环境中。对于这方面的详细源代码或者技术支持感兴趣的话,如能提供一定报酬的基础上,可使用站内消息联系博主转让!
当然如果免费使用的话,附件中的cmipcrypt.dll是没有任何限制,随便使用。
浙公网安备 33010602011771号