Skip to content

Commit 2fefdfe

Browse files
committed
发布1.5版本
1 parent 96a6c71 commit 2fefdfe

File tree

6 files changed

+177
-338
lines changed

6 files changed

+177
-338
lines changed

Program.cs

Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,22 @@ namespace com.github.xiangyuecn.rsacsharp {
66
/// GitHub: https://github.com/xiangyuecn/RSA-csharp
77
/// </summary>
88
class Program {
9-
static void RSA_ForCoreTest(bool fast) {
10-
Console.WriteLine(hr);
11-
Console.WriteLine(ht + " RSA_ForCoreTest:仅限.NET Core下可测试 " + ht);
12-
Console.WriteLine(hr);
13-
14-
Console.WriteLine("RSA_ForCore:只支持.NET Core环境,可跨平台使用。如需在.NET Framework中使用,请用RSA_ForWindows(也支持.NET Core,但只能Windows系统中使用)。");
15-
Console.WriteLine();
16-
if (!RSA_ForCore.IS_CORE) {
17-
Console.WriteLine("非.NET Core环境,不测试!");
18-
return;
19-
}
20-
9+
static void RSATest(bool fast) {
2110
//新生成一个RSA密钥,也可以通过已有的pem、xml文本密钥来创建RSA
22-
var rsa = new RSA_ForCore(512);
23-
// var rsa = new RSA_ForCore("pem或xml文本密钥");
24-
// var rsa = new RSA_ForCore(RSA_PEM.FromPEM("pem文本密钥"));
25-
// var rsa = new RSA_ForCore(RSA_PEM.FromXML("xml文本密钥"));
26-
27-
ForXxxxxxTest(rsa, fast);
28-
}
29-
static void RSA_ForWindowsTest(bool fast) {
30-
Console.WriteLine(hr);
31-
Console.WriteLine(ht + " RSA_ForWindowsTest:仅限Windows系统可测试 " + ht);
32-
Console.WriteLine(hr);
33-
34-
Console.WriteLine("RSA_ForWindows:.NET Core、.NET Framework均可用,但由于使用的RSACryptoServiceProvider不支持跨平台,只支持在Windows系统中使用,要跨平台请使用仅支持.NET Core的RSA_ForCore。");
35-
Console.WriteLine();
36-
if (!isWindows) {
37-
Console.WriteLine("非Windows系统,不测试!");
38-
return;
39-
}
40-
41-
//新生成一个RSA密钥,也可以通过已有的pem、xml文本密钥来创建RSA
42-
var rsa = new RSA_ForWindows(512);
43-
// var rsa = new RSA_ForWindows("pem或xml文本密钥");
44-
// var rsa = new RSA_ForWindows(RSA_PEM.FromPEM("pem文本密钥"));
45-
// var rsa = new RSA_ForWindows(RSA_PEM.FromXML("xml文本密钥"));
46-
47-
ForXxxxxxTest(rsa, fast);
48-
}
11+
var rsa = new RSA_Util(512);
12+
// var rsa = new RSA_Util("pem或xml文本密钥");
13+
// var rsa = new RSA_Util(RSA_PEM.FromPEM("pem文本密钥"));
14+
// var rsa = new RSA_Util(RSA_PEM.FromXML("xml文本密钥"));
4915

50-
51-
52-
static void ForXxxxxxTest(dynamic forXxxxxx, bool fast) {
53-
dynamic rsa = forXxxxxx;
54-
//两种rsa都有相同的方法,为什么没有抽象类,因为懒,实际使用应当有明确的类型,就像下面两行,解开注释就能恢复正常
55-
// RSA_ForWindows rsa = (RSA_ForWindows)forXxxxxx;
56-
// RSA_ForCore rsa = (RSA_ForCore)forXxxxxx;
16+
if (!checkPlatform(rsa)) return;
5717

5818
//提取密钥pem字符串
5919
string pem_pkcs1 = rsa.ToPEM().ToPEM_PKCS1();
6020
string pem_pkcs8 = rsa.ToPEM().ToPEM_PKCS8();
6121
//提取密钥xml字符串
6222
string xml = rsa.ToXML();
6323

64-
Console.WriteLine("【" + rsa.KeySize + "私钥(XML)】:");
24+
AssertMsg("【" + rsa.KeySize + "私钥(XML)】:", rsa.KeySize == 512);
6525
Console.WriteLine(xml);
6626
Console.WriteLine();
6727
Console.WriteLine("【" + rsa.KeySize + "私钥(PKCS#1)】:");
@@ -93,14 +53,14 @@ static void ForXxxxxxTest(dynamic forXxxxxx, bool fast) {
9353
Console.WriteLine();
9454

9555
//用pem文本创建RSA
96-
var rsa2 = new RSA_ForWindows(RSA_PEM.FromPEM(pem_pkcs8));
56+
var rsa2 = new RSA_Util(RSA_PEM.FromPEM(pem_pkcs8));
9757
Console.WriteLine("【用PEM新创建的RSA是否和上面的一致】:");
9858
Assert("XML:", rsa2.ToXML() == rsa.ToXML());
9959
Assert("PKCS1:", rsa2.ToPEM().ToPEM_PKCS1() == rsa.ToPEM().ToPEM_PKCS1());
10060
Assert("PKCS8:", rsa2.ToPEM().ToPEM_PKCS8() == rsa.ToPEM().ToPEM_PKCS8());
10161

10262
//用xml文本创建RSA
103-
var rsa3 = new RSA_ForWindows(RSA_PEM.FromXML(xml));
63+
var rsa3 = new RSA_Util(RSA_PEM.FromXML(xml));
10464
Console.WriteLine("【用XML新创建的RSA是否和上面的一致】:");
10565
Assert("XML:", rsa3.ToXML() == rsa.ToXML());
10666
Assert("PKCS1:", rsa3.ToPEM().ToPEM_PKCS1() == rsa.ToPEM().ToPEM_PKCS1());
@@ -121,7 +81,7 @@ static void ForXxxxxxTest(dynamic forXxxxxx, bool fast) {
12181
}
12282
//--------RSA_PEM公钥验证---------
12383
{
124-
var rsaPublic = new RSA_ForWindows(rsa.ToPEM(true));
84+
var rsaPublic = new RSA_Util(rsa.ToPEM(true));
12585
RSA_PEM pem = rsaPublic.ToPEM();
12686
Console.WriteLine("【RSA_PEM仅公钥是否和原始RSA一致】:");
12787
Console.WriteLine(pem.KeySize + "位");
@@ -132,7 +92,7 @@ static void ForXxxxxxTest(dynamic forXxxxxx, bool fast) {
13292

13393
if (!fast) {
13494
RSA_PEM pem = rsa.ToPEM();
135-
var rsa4 = new RSA_ForWindows(new RSA_PEM(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D));
95+
var rsa4 = new RSA_Util(new RSA_PEM(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D));
13696
Console.WriteLine("【用n、e、d构造解密】");
13797
de = rsa4.DecodeOrNull(en);
13898
AssertMsg(de, de == str);
@@ -159,28 +119,55 @@ static void AssertMsg(string msg, bool check) {
159119
Console.WriteLine(msg);
160120
}
161121

162-
static readonly string ht = "◆◆◆◆◆◆◆◆◆◆◆◆";
163-
static readonly string hr = "---------------------------------------------------------";
164-
static bool isWindows = true;
165-
static void Main(string[] _) {
122+
static bool checkPlatform(RSA_Util rsa) {
123+
Console.WriteLine(hr);
124+
Console.WriteLine(ht + " "
125+
+ (RSA_Util.UseCore == RSA_Util.IS_CORE ? "【默认RSA实现】" : "【强制切换RSA实现类】")
126+
+ "当前RSA实现类:" + rsa.RSAObject.GetType().Name
127+
+ " " + ht);
128+
Console.WriteLine(hr);
129+
if (RSA_Util.UseCore == RSA_Util.IS_CORE) {
130+
return true;
131+
}
132+
133+
134+
var isWindows = true;
166135
#if (NETCOREAPP || NETSTANDARD || NET) //https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/preprocessor-directives
167136
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) {
168137
isWindows = false;
169138
}
170139
#endif
171140

172-
//for (var i = 0; i < 1000; i++) { Console.WriteLine("第"+i+"次>>>>>"); RSA_ForCoreTest(true); RSA_ForWindowsTest(true); }
141+
//强制切换了RSA实现类,检查一下是否支持
142+
if (!rsa.RSAIsUseCore) {// RSACryptoServiceProvider实现类
143+
if (!isWindows) {
144+
Console.WriteLine("强制切换了RSA实现类,当前使用的RSACryptoServiceProvider不支持跨平台,只支持在Windows系统中使用。");
145+
Console.WriteLine("非Windows系统,不测试!");
146+
return false;
147+
}
148+
}
149+
return true;
150+
}
151+
152+
static readonly string ht = "◆◆◆◆◆◆◆◆◆◆◆◆";
153+
static readonly string hr = "---------------------------------------------------------";
154+
static void Main(string[] _) {
155+
long startTime = DateTime.Now.Ticks;
156+
157+
// for (var i = 0; i < 1000; i++) { Console.WriteLine("第" + i + "次>>>>>"); RSA_Util.UseCore = !RSA_Util.IS_CORE; RSATest(true); RSA_Util.UseCore = RSA_Util.IS_CORE; RSATest(true); }
173158

174-
RSA_ForCoreTest(false);
159+
RSATest(false);
175160

176161
Console.WriteLine(hr);
177162
Console.WriteLine();
178163

179-
RSA_ForWindowsTest(false);
164+
// 强制切换一下RSA实现类进行测试
165+
RSA_Util.UseCore = !RSA_Util.IS_CORE;
166+
RSATest(false);
180167
Console.WriteLine();
181168

182169
Console.WriteLine(hr);
183-
Console.WriteLine(ht + " 回车退出... " + ht);
170+
Console.WriteLine(ht + " 耗时:" + (DateTime.Now.Ticks - startTime) / 10000 + "ms 回车退出... " + ht);
184171
Console.WriteLine(hr);
185172
Console.WriteLine();
186173
Console.ReadLine();

README.md

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
你可以只copy `RSA_PEM.cs` 文件到你的项目中使用,只需这一个文件你就拥有了通过PEM格式密钥创建`RSA``RSACryptoServiceProvider`的能力。也可以clone整个项目代码用vs直接打开进行测试。
88

9-
底层实现采用PEM文件二进制层面上进行字节码解析,简单轻巧0依赖;附带实现了两个RSA封装操作类(`RSA_ForCore.cs``RSA_ForWindows.cs`),和一个测试控制台程序(`Program.cs`)。
9+
底层实现采用PEM文件二进制层面上进行字节码解析,简单轻巧0依赖;附带实现了一个RSA封装操作类(`RSA_Util.cs`),和一个测试控制台程序(`Program.cs`)。
1010

11-
源文件|平台支持|功能说明|限制
11+
源文件|平台支持|功能说明|依赖项
1212
:-:|:-:|:-|:-
1313
**RSA_PEM.cs**|.NET Core、.NET Framework|用于解析和导出PEM,创建RSA实例|无
14-
**RSA_ForWindows.cs**|.NET Core、.NET Framework|RSA操作类,封装了加密、解密、验签|只支持在Windows系统中使用,因为使用的RSACryptoServiceProvider不支持跨平台
15-
**RSA_ForCore.cs**|.NET Core|RSA操作类,封装了加密、解密、验签|只支持.NET Core环境,可跨平台使用
14+
**RSA_Util.cs**|.NET Core、.NET Framework|RSA操作类,封装了加密、解密、验签|RSA_PEM
15+
Program.cs|.NET Core.NET Framework|测试控制台程序|RSA_PEM、RSA_Util
1616

1717
**如需功能定制,网站、App、小程序开发等需求,请加本文档下面的QQ群,联系群主(即作者),谢谢~**
1818

@@ -42,11 +42,8 @@
4242
var pem=RSA_PEM.FromPEM("-----BEGIN XXX KEY-----..此处意思意思..-----END XXX KEY-----");
4343

4444
//直接创建RSA操作类
45-
var rsa=new RSA_ForWindows(pem); //这个只能在Windows系统里面运行
46-
//var rsa=new RSA_ForCore(pem); //这个支持跨平台,但只支持.NET Core
47-
48-
//var rsa=new RSA_ForWindows(2048); //也可以直接生成新密钥,rsa.ToPEM()得到pem对象
49-
//var rsa=new RSA_ForCore(2048);
45+
var rsa=new RSA_Util(pem);
46+
//var rsa=new RSA_Util(2048); //也可以直接生成新密钥,rsa.ToPEM()得到pem对象
5047
5148
//加密
5249
var enTxt=rsa.Encode("测试123");
@@ -150,25 +147,27 @@ Framework项目里面需要引入程序集`System.Numerics`用来支持`BigInteg
150147

151148

152149

153-
## RSA_ForWindows.cs】【RSA_ForCore.cs】
154-
这两文件依赖`RSA_PEM.cs`两个类的方法都是相同的(未做抽象,因为懒,要用那个就直接用哪个),封装了加密、解密、签名、验证、秘钥导入导出操作。
150+
## RSA_Util.cs】
151+
这个文件依赖`RSA_PEM.cs`,封装了加密、解密、签名、验证、秘钥导入导出操作;.NET Core下由实际的RSA实现类提供支持,.NET Framework下由RSACryptoServiceProvider提供支持
155152

156153
### 构造方法
157154

158-
**RSA_For??(int keySize)**:用指定密钥大小创建一个新的RSA,会生成新密钥,出错抛异常。
155+
**RSA_Util(int keySize)**:用指定密钥大小创建一个新的RSA,会生成新密钥,出错抛异常。
159156

160-
**RSA_For??(string pemOrXML)**:通过`PEM格式``XML格式`密钥,创建一个RSA,pem或xml内可以只包含一个公钥或私钥,或都包含,出错抛异常。`XML格式`如:`<RSAKeyValue><Modulus>...</RSAKeyValue>`。pem支持`PKCS#1``PKCS#8`格式,格式如:`-----BEGIN XXX KEY-----....-----END XXX KEY-----`
157+
**RSA_Util(string pemOrXML)**:通过`PEM格式``XML格式`密钥,创建一个RSA,pem或xml内可以只包含一个公钥或私钥,或都包含,出错抛异常。`XML格式`如:`<RSAKeyValue><Modulus>...</RSAKeyValue>`。pem支持`PKCS#1``PKCS#8`格式,格式如:`-----BEGIN XXX KEY-----....-----END XXX KEY-----`
161158

162-
**RSA_For??(RSA_PEM pem)**:通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常。
159+
**RSA_Util(RSA_PEM pem)**:通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常。
163160

164-
**RSA_For??(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ)**:本方法会先生成RSA_PEM再创建RSA。通过全量的PEM字段数据构造一个PEM,除了模数modulus和公钥指数exponent必须提供外,其他私钥指数信息要么全部提供,要么全部不提供(导出的PEM就只包含公钥)注意:所有参数首字节如果是0,必须先去掉。
161+
**RSA_Util(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ)**:本方法会先生成RSA_PEM再创建RSA。通过全量的PEM字段数据构造一个PEM,除了模数modulus和公钥指数exponent必须提供外,其他私钥指数信息要么全部提供,要么全部不提供(导出的PEM就只包含公钥)注意:所有参数首字节如果是0,必须先去掉。
165162

166-
**RSA_For??(byte[] modulus, byte[] exponent, byte[] dOrNull)**:本方法会先生成RSA_PEM再创建RSA。通过公钥指数和私钥指数构造一个PEM,会反推计算出P、Q但和原始生成密钥的P、Q极小可能相同。注意:所有参数首字节如果是0,必须先去掉。出错将会抛出异常。私钥指数可以不提供,导出的PEM就只包含公钥。
163+
**RSA_Util(byte[] modulus, byte[] exponent, byte[] dOrNull)**:本方法会先生成RSA_PEM再创建RSA。通过公钥指数和私钥指数构造一个PEM,会反推计算出P、Q但和原始生成密钥的P、Q极小可能相同。注意:所有参数首字节如果是0,必须先去掉。出错将会抛出异常。私钥指数可以不提供,导出的PEM就只包含公钥。
167164

168165

169166
### 实例属性
170167

171-
`RSA`|`RSACryptoServiceProvider` **RSAObject**:最底层的RSA或RSACryptoServiceProvider对象。
168+
`RSA` **RSAObject**:最底层的RSA对象,.NET Core下为实际的RSA实现类,.NET Framework下RSACryptoServiceProvider。
169+
170+
`bool` **RSAIsUseCore**:最底层的RSA对象是否是使用的rsaCore(RSA),否则将是使用的rsaFramework(RSACryptoServiceProvider)。
172171

173172
`int` **KeySize**:密钥位数。
174173

0 commit comments

Comments
 (0)