Skip to content

Commit 68ef91d

Browse files
committed
升级1.2版本: 公钥也区分PKCS#1和PKCS#8
1 parent f0c8e01 commit 68ef91d

File tree

5 files changed

+136
-61
lines changed

5 files changed

+136
-61
lines changed

Program.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ static void RSATest() {
1111
Console.WriteLine("【" + rsa.KeySize + "私钥(XML)】:");
1212
Console.WriteLine(rsa.ToXML());
1313
Console.WriteLine();
14-
Console.WriteLine("【" + rsa.KeySize + "私钥(PEM)】:");
15-
Console.WriteLine(rsa.ToPEM_PKCS1());
14+
Console.WriteLine("【" + rsa.KeySize + "私钥(PKCS#1)】:");
15+
Console.WriteLine(rsa.ToPEM().ToPEM_PKCS1());
1616
Console.WriteLine();
17-
Console.WriteLine("【" + rsa.KeySize + "公钥(PEM)】:");
18-
Console.WriteLine(rsa.ToPEM_PKCS1(true));
17+
Console.WriteLine("【" + rsa.KeySize + "公钥(PKCS#8)】:");
18+
Console.WriteLine(rsa.ToPEM().ToPEM_PKCS8(true));
1919
Console.WriteLine();
2020

2121
var str = "abc内容123";
@@ -30,33 +30,44 @@ static void RSATest() {
3030
Console.WriteLine(rsa.Sign("SHA1", str));
3131
Console.WriteLine();
3232

33-
var rsa2 = new RSA(rsa.ToPEM_PKCS8(), true);
33+
var rsa2 = new RSA(rsa.ToPEM().ToPEM_PKCS8(), true);
3434
Console.WriteLine("【用PEM新创建的RSA是否和上面的一致】:");
3535
Console.WriteLine("XML:" + (rsa2.ToXML() == rsa.ToXML()));
36-
Console.WriteLine("PKCS1:" + (rsa2.ToPEM_PKCS1() == rsa.ToPEM_PKCS1()));
37-
Console.WriteLine("PKCS8:" + (rsa2.ToPEM_PKCS8() == rsa.ToPEM_PKCS8()));
36+
Console.WriteLine("PKCS1:" + (rsa2.ToPEM().ToPEM_PKCS1() == rsa.ToPEM().ToPEM_PKCS1()));
37+
Console.WriteLine("PKCS8:" + (rsa2.ToPEM().ToPEM_PKCS8() == rsa.ToPEM().ToPEM_PKCS8()));
3838

3939
var rsa3 = new RSA(rsa.ToXML());
4040
Console.WriteLine("【用XML新创建的RSA是否和上面的一致】:");
4141
Console.WriteLine("XML:" + (rsa3.ToXML() == rsa.ToXML()));
42-
Console.WriteLine("PKCS1:" + (rsa3.ToPEM_PKCS1() == rsa.ToPEM_PKCS1()));
43-
Console.WriteLine("PKCS8:" + (rsa3.ToPEM_PKCS8() == rsa.ToPEM_PKCS8()));
42+
Console.WriteLine("PKCS1:" + (rsa3.ToPEM().ToPEM_PKCS1() == rsa.ToPEM().ToPEM_PKCS1()));
43+
Console.WriteLine("PKCS8:" + (rsa3.ToPEM().ToPEM_PKCS8() == rsa.ToPEM().ToPEM_PKCS8()));
4444

4545
//--------RSA_PEM验证---------
4646
RSA_PEM pem = rsa.ToPEM();
4747
Console.WriteLine("【RSA_PEM是否和原始RSA一致】:");
4848
Console.WriteLine(pem.KeySize + "位");
4949
Console.WriteLine("XML:" + (pem.ToXML(false) == rsa.ToXML()));
50-
Console.WriteLine("PKCS1:" + (pem.ToPEM(false, false) == rsa.ToPEM_PKCS1()));
51-
Console.WriteLine("PKCS8:" + (pem.ToPEM(false, true) == rsa.ToPEM_PKCS8()));
50+
Console.WriteLine("PKCS1:" + (pem.ToPEM_PKCS1() == rsa.ToPEM().ToPEM_PKCS1()));
51+
Console.WriteLine("PKCS8:" + (pem.ToPEM_PKCS8() == rsa.ToPEM().ToPEM_PKCS8()));
5252
Console.WriteLine("仅公钥:");
5353
Console.WriteLine("XML:" + (pem.ToXML(true) == rsa.ToXML(true)));
54-
Console.WriteLine("PKCS1:" + (pem.ToPEM(true, false) == rsa.ToPEM_PKCS1(true)));
55-
Console.WriteLine("PKCS8:" + (pem.ToPEM(true, true) == rsa.ToPEM_PKCS8(true)));
54+
Console.WriteLine("PKCS1:" + (pem.ToPEM_PKCS1(true) == rsa.ToPEM().ToPEM_PKCS1(true)));
55+
Console.WriteLine("PKCS8:" + (pem.ToPEM_PKCS8(true) == rsa.ToPEM().ToPEM_PKCS8(true)));
5656

5757
var rsa4 = new RSA(new RSA_PEM(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D));
5858
Console.WriteLine("【用n、e、d构造解密】");
5959
Console.WriteLine(rsa4.DecodeOrNull(en));
60+
61+
62+
63+
64+
Console.WriteLine();
65+
Console.WriteLine();
66+
Console.WriteLine("【" + rsa.KeySize + "私钥(PKCS#8)】:");
67+
Console.WriteLine(rsa.ToPEM().ToPEM_PKCS8());
68+
Console.WriteLine();
69+
Console.WriteLine("【" + rsa.KeySize + "公钥(PKCS#1)】:不常见的公钥格式");
70+
Console.WriteLine(rsa.ToPEM().ToPEM_PKCS1(true));
6071
}
6172

6273

Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@
2929
// 生成号
3030
// 修订号
3131
//
32-
[assembly: AssemblyVersion("1.1.0.0")]
33-
[assembly: AssemblyFileVersion("1.1.0.0")]
32+
[assembly: AssemblyVersion("1.2.0.0")]
33+
[assembly: AssemblyFileVersion("1.2.0.0")]

README.md

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
项目里面需要引入程序集`System.Numerics`用来支持`BigInteger`,vs默认创建的项目是不会自动引入此程序集的,要手动引入。
3939

40-
注:openssl `RSAPublicKey_out`导出的公钥,字节码内并不带[OID](http://www.oid-info.com/get/1.2.840.113549.1.1.1)(目测是因为不带OID所以openssl自己都不支持用这个公钥来加密数据),RSA_PEM支持此格式公钥的导入,但不提供此种格式公钥的导出
40+
注:`openssl rsa -in 私钥文件 -pubout`导出的是PKCS#8格式公钥(用的比较多),`openssl rsa -pubin -in PKCS#8公钥文件 -RSAPublicKey_out`导出的是PKCS#1格式公钥(用的比较少)
4141

4242

4343
### 构造方法
@@ -64,7 +64,11 @@ bool:**HasPrivate**(是否包含私钥)
6464

6565
**RSACryptoServiceProvider GetRSA()**:将PEM中的公钥私钥转成RSA对象,如果未提供私钥,RSA中就只包含公钥。
6666

67-
**string ToPEM(bool convertToPublic, bool usePKCS8)**:将RSA中的密钥对转换成PEM格式,usePKCS8=false时返回PKCS#1格式,否则返回PKCS#8格式,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响。
67+
**string ToPEM(bool convertToPublic, bool privateUsePKCS8, bool publicUsePKCS8)**:将RSA中的密钥对转换成PEM格式。convertToPublic:等于true时含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响 。**privateUsePKCS8**:私钥的返回格式,等于true时返回PKCS#8格式(`-----BEGIN PRIVATE KEY-----`),否则返回PKCS#1格式(`-----BEGIN RSA PRIVATE KEY-----`),返回公钥时此参数无效;两种格式使用都比较常见。**publicUsePKCS8**:公钥的返回格式,等于true时返回PKCS#8格式(`-----BEGIN PUBLIC KEY-----`),否则返回PKCS#1格式(`-----BEGIN RSA PUBLIC KEY-----`),返回私钥时此参数无效;一般用的多的是true PKCS#8格式公钥,PKCS#1格式公钥似乎比较少见。
68+
69+
**string ToPEM_PKCS1(bool convertToPublic=false)**:ToPEM方法的简化写法,不管公钥还是私钥都返回PKCS#1格式;似乎导出PKCS#1公钥用的比较少,PKCS#8的公钥用的多些,私钥#1#8都差不多。
70+
71+
**string ToPEM_PKCS8(bool convertToPublic=false)**:ToPEM方法的简化写法,不管公钥还是私钥都返回PKCS#8格式。
6872

6973
**string ToXML(bool convertToPublic)**:将RSA中的密钥对转换成XML格式,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响。
7074

@@ -91,6 +95,10 @@ bool:**HasPrivate**(是否包含私钥)
9195

9296
**RSA(RSA_PEM pem)**:通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常。
9397

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

95103
### 实例属性
96104

@@ -105,11 +113,7 @@ bool:**HasPrivate**(是否包含私钥)
105113

106114
**string ToXML(bool convertToPublic = false)**:导出`XML格式`秘钥对。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。
107115

108-
**string ToPEM_PKCS1(bool convertToPublic = false)**:导出`PEM PKCS#1格式`秘钥对。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。
109-
110-
**string ToPEM_PKCS8(bool convertToPublic = false)**:导出`PEM PKCS#8格式`秘钥对。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。
111-
112-
**RSA_PEM ToPEM(bool convertToPublic = false)**:导出RSA_PEM对象,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响。
116+
**RSA_PEM ToPEM(bool convertToPublic = false)**:导出RSA_PEM对象,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响;通过RSA_PEM.ToPEM方法可以导出PEM文本。
113117

114118
**string Encode(string str)**:加密操作,支持任意长度数据。
115119

@@ -189,19 +193,18 @@ PEM格式中,每段数据基本上都是`type+长度数据占用位数+长度
189193
内容前面要加0(可能现在全部是加0吧,数据结尾这个字节不满8位?什么情况下会出现不够1字节?不够就用二进制0补齐,然后内容前面加补了几位)。
190194

191195

192-
### PEM公钥编码格式
193-
`PKCS#1``PKCS#8`公钥编码都是统一的格式。
196+
### PEM PKCS#8公钥编码格式
194197

195198
```
196-
/*****1024位公钥*****/
199+
/*****1024位PKCS#8公钥*****/
197200
-----BEGIN PUBLIC KEY-----
198201
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYw9+M3+REzDtYqwBrs/as/Oy8
199202
GRE5OmnqOV0EfkEiCIjiczbVEFnZ3qRjLbDATfmBxNQ6c6Fga8nX28glEH/aL/RG
200203
2KdpI8KMUqKAszNydsHSeh9MSKcd5zgS4NuE0u+eR7CB8kOWipiLDQmY38kpM36p
201204
RWdNQlpIaTDo5IhJJwIDAQAB
202205
-----END PUBLIC KEY-----
203206
204-
/*****二进制表述*****/
207+
/*****二进制表述(文本是16进制下同)*****/
205208
30819F300D06092A864886F70D010101050003818D003081890281810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E48849270203010001
206209
207210
@@ -221,7 +224,6 @@ RWdNQlpIaTDo5IhJJwIDAQAB
221224
, 30_SEQUENCE:{
222225
02_INTEGER: "整数"
223226
, 02_INTEGER: "整数"
224-
, 02_INTEGER: "整数"
225227
}
226228
}
227229
*/
@@ -260,6 +262,33 @@ RWdNQlpIaTDo5IhJJwIDAQAB
260262
```
261263

262264

265+
### PEM PKCS#1公钥编码格式
266+
267+
```
268+
/*****1024位PKCS#1公钥*****/
269+
-----BEGIN RSA PUBLIC KEY-----
270+
MIGJAoGBAJjD34zf5ETMO1irAGuz9qz87LwZETk6aeo5XQR+QSIIiOJzNtUQWdne
271+
pGMtsMBN+YHE1DpzoWBrydfbyCUQf9ov9EbYp2kjwoxSooCzM3J2wdJ6H0xIpx3n
272+
OBLg24TS755HsIHyQ5aKmIsNCZjfySkzfqlFZ01CWkhpMOjkiEknAgMBAAE=
273+
-----END RSA PUBLIC KEY-----
274+
275+
/*****二进制表述*****/
276+
3081890281810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E48849270203010001
277+
278+
279+
/*****二进制分解(和PKCS#8公钥格式就是只留了N、E两个数据,及其简单)*****/
280+
30 81 89
281+
282+
/*RSA Modulus*/
283+
02 81 81
284+
0098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E4884927
285+
286+
/*RSA Exponent*/
287+
02 03
288+
010001
289+
```
290+
291+
263292
### PEM PKCS#1私钥编码格式
264293

265294
```
@@ -398,7 +427,7 @@ openssl genrsa -out private.pem 1024
398427
::提取公钥PKCS#8
399428
openssl rsa -in private.pem -pubout -out public.pem
400429
401-
::转换成RSAPublicKey PKCS#1?
430+
::转换成RSAPublicKey PKCS#1
402431
openssl rsa -pubin -in public.pem -RSAPublicKey_out -out public.pem.rsakey
403432
404433
::加密
@@ -407,8 +436,8 @@ echo abcd123 | openssl rsautl -encrypt -inkey public.pem -pubin -out data.enc.bi
407436
::解密
408437
openssl rsautl -decrypt -in data.enc.bin -inkey private.pem -out data.dec.txt
409438
410-
::测试RSAPublicKey PKCS#1?,不出意外会出错
411-
::因为这个公钥里面没有OID,通过RSA_PEM转换成PKCS#1自动带上OID就能正常加密
439+
::测试RSAPublicKey PKCS#1,不出意外会出错
440+
::因为这个公钥里面没有OID,通过RSA_PEM转换成PKCS#8自动带上OID就能正常加密
412441
echo abcd123 | openssl rsautl -encrypt -inkey public.pem.rsakey -pubin
413442
```
414443

RSA.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ public string ToXML(bool convertToPublic = false) {
1616
return rsa.ToXmlString(!rsa.PublicOnly && !convertToPublic);
1717
}
1818
/// <summary>
19-
/// 导出PEM PKCS#1格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
20-
/// </summary>
21-
public string ToPEM_PKCS1(bool convertToPublic = false) {
22-
return new RSA_PEM(rsa).ToPEM(convertToPublic, false);
23-
}
24-
/// <summary>
25-
/// 导出PEM PKCS#8格式密钥对,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
26-
/// </summary>
27-
public string ToPEM_PKCS8(bool convertToPublic = false) {
28-
return new RSA_PEM(rsa).ToPEM(convertToPublic, true);
29-
}
30-
/// <summary>
3119
/// 将密钥对导出成PEM对象,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
3220
/// </summary>
3321
public RSA_PEM ToPEM(bool convertToPublic = false) {
@@ -213,5 +201,23 @@ public RSA(string pem, bool noop) {
213201
public RSA(RSA_PEM pem) {
214202
rsa = pem.GetRSA();
215203
}
204+
/// <summary>
205+
/// 本方法会先生成RSA_PEM再创建RSA:通过公钥指数和私钥指数构造一个PEM,会反推计算出P、Q但和原始生成密钥的P、Q极小可能相同
206+
/// 注意:所有参数首字节如果是0,必须先去掉
207+
/// 出错将会抛出异常
208+
/// </summary>
209+
/// <param name="modulus">必须提供模数</param>
210+
/// <param name="exponent">必须提供公钥指数</param>
211+
/// <param name="dOrNull">私钥指数可以不提供,导出的PEM就只包含公钥</param>
212+
public RSA(byte[] modulus, byte[] exponent, byte[] dOrNull) {
213+
rsa = new RSA_PEM(modulus, exponent, dOrNull).GetRSA();
214+
}
215+
/// <summary>
216+
/// 本方法会先生成RSA_PEM再创建RSA:通过全量的PEM字段数据构造一个PEM,除了模数modulus和公钥指数exponent必须提供外,其他私钥指数信息要么全部提供,要么全部不提供(导出的PEM就只包含公钥)
217+
/// 注意:所有参数首字节如果是0,必须先去掉
218+
/// </summary>
219+
public RSA(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ) {
220+
rsa = new RSA_PEM(modulus, exponent, d, p, q, dp, dq, inverseQ).GetRSA();
221+
}
216222
}
217223
}

RSA_PEM.cs

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ static public RSA_PEM FromPEM(string pem) {
295295
//读取数据总长度
296296
readLen(0x30);
297297

298-
//看看有没有oid
298+
//检测PKCS8
299299
var idx2 = idx;
300300
if (eq(_SeqOID)) {
301301
//读取1长度
@@ -363,11 +363,30 @@ static public RSA_PEM FromPEM(string pem) {
363363

364364

365365

366-
367366
/// <summary>
368-
/// 将RSA中的密钥对转换成PEM格式,usePKCS8=false时返回PKCS#1格式,否则返回PKCS#8格式,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
367+
/// 将RSA中的密钥对转换成PEM PKCS#1格式
368+
/// 。convertToPublic:等于true时含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
369+
/// 。公钥如:-----BEGIN RSA PUBLIC KEY-----,私钥如:-----BEGIN RSA PRIVATE KEY-----
370+
/// 。似乎导出PKCS#1公钥用的比较少,PKCS#8的公钥用的多些,私钥#1#8都差不多
369371
/// </summary>
370-
public string ToPEM(bool convertToPublic, bool usePKCS8) {
372+
public string ToPEM_PKCS1(bool convertToPublic = false) {
373+
return ToPEM(convertToPublic, false, false);
374+
}
375+
/// <summary>
376+
/// 将RSA中的密钥对转换成PEM PKCS#8格式
377+
/// 。convertToPublic:等于true时含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
378+
/// 。公钥如:-----BEGIN PUBLIC KEY-----,私钥如:-----BEGIN PRIVATE KEY-----
379+
/// </summary>
380+
public string ToPEM_PKCS8(bool convertToPublic = false) {
381+
return ToPEM(convertToPublic, true, true);
382+
}
383+
/// <summary>
384+
/// 将RSA中的密钥对转换成PEM格式
385+
/// 。convertToPublic:等于true时含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
386+
/// 。privateUsePKCS8:私钥的返回格式,等于true时返回PKCS#8格式(-----BEGIN PRIVATE KEY-----),否则返回PKCS#1格式(-----BEGIN RSA PRIVATE KEY-----),返回公钥时此参数无效;两种格式使用都比较常见
387+
/// 。publicUsePKCS8:公钥的返回格式,等于true时返回PKCS#8格式(-----BEGIN PUBLIC KEY-----),否则返回PKCS#1格式(-----BEGIN RSA PUBLIC KEY-----),返回私钥时此参数无效;一般用的多的是true PKCS#8格式公钥,PKCS#1格式似乎比较少见公钥
388+
/// </summary>
389+
public string ToPEM(bool convertToPublic, bool privateUsePKCS8, bool publicUsePKCS8) {
371390
//https://www.jianshu.com/p/25803dd9527d
372391
//https://www.cnblogs.com/ylz8401/p/8443819.html
373392
//https://blog.csdn.net/jiayanhui2877/article/details/47187077
@@ -440,18 +459,22 @@ public string ToPEM(bool convertToPublic, bool usePKCS8) {
440459
ms.WriteByte(0x30);
441460
var index1 = (int)ms.Length;
442461

443-
//固定内容
444-
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
445-
writeAll(ms, _SeqOID);
462+
//PKCS8 多一段数据
463+
int index2 = -1, index3 = -1;
464+
if (publicUsePKCS8) {
465+
//固定内容
466+
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
467+
writeAll(ms, _SeqOID);
446468

447-
//从0x00开始的后续长度
448-
ms.WriteByte(0x03);
449-
var index2 = (int)ms.Length;
450-
ms.WriteByte(0x00);
469+
//从0x00开始的后续长度
470+
ms.WriteByte(0x03);
471+
index2 = (int)ms.Length;
472+
ms.WriteByte(0x00);
451473

452-
//后续内容长度
453-
ms.WriteByte(0x30);
454-
var index3 = (int)ms.Length;
474+
//后续内容长度
475+
ms.WriteByte(0x30);
476+
index3 = (int)ms.Length;
477+
}
455478

456479
//写入Modulus
457480
writeBlock(Key_Modulus);
@@ -463,12 +486,18 @@ public string ToPEM(bool convertToPublic, bool usePKCS8) {
463486
//计算空缺的长度
464487
var byts = ms.ToArray();
465488

466-
byts = writeLen(index3, byts);
467-
byts = writeLen(index2, byts);
489+
if (index2 != -1) {
490+
byts = writeLen(index3, byts);
491+
byts = writeLen(index2, byts);
492+
}
468493
byts = writeLen(index1, byts);
469494

470495

471-
return "-----BEGIN PUBLIC KEY-----\n" + TextBreak(Convert.ToBase64String(byts), 64) + "\n-----END PUBLIC KEY-----";
496+
var flag = " PUBLIC KEY";
497+
if (!publicUsePKCS8) {
498+
flag = " RSA" + flag;
499+
}
500+
return "-----BEGIN" + flag + "-----\n" + TextBreak(Convert.ToBase64String(byts), 64) + "\n-----END" + flag + "-----";
472501
} else {
473502
/****生成私钥****/
474503

@@ -481,7 +510,7 @@ public string ToPEM(bool convertToPublic, bool usePKCS8) {
481510

482511
//PKCS8 多一段数据
483512
int index2 = -1, index3 = -1;
484-
if (usePKCS8) {
513+
if (privateUsePKCS8) {
485514
//固定内容
486515
writeAll(ms, _SeqOID);
487516

@@ -519,7 +548,7 @@ public string ToPEM(bool convertToPublic, bool usePKCS8) {
519548

520549

521550
var flag = " PRIVATE KEY";
522-
if (!usePKCS8) {
551+
if (!privateUsePKCS8) {
523552
flag = " RSA" + flag;
524553
}
525554
return "-----BEGIN" + flag + "-----\n" + TextBreak(Convert.ToBase64String(byts), 64) + "\n-----END" + flag + "-----";

0 commit comments

Comments
 (0)