- Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathExportHelper.cs
107 lines (103 loc) · 4.22 KB
/
ExportHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
usingSystem;
usingSystem.IO;
usingSystem.Security.Cryptography;
usingSystem.Security.Cryptography.X509Certificates;
namespaceACMECLI
{
publicclassExportHelper
{
publicstaticvoidExportPrivateKey(RSArsa,TextWriteroutputStream)
// private static void ExportPrivateKey(RSACryptoServiceProvider csp, TextWriter outputStream)
{
// Original rsa arg was RSACryptoServiceProvider csp:
// if (csp.PublicOnly) throw new ArgumentException("CSP does not contain a private key", "csp");
varparameters=rsa.ExportParameters(true);
using(varstream=newMemoryStream())
{
varwriter=newBinaryWriter(stream);
writer.Write((byte)0x30);// SEQUENCE
using(varinnerStream=newMemoryStream())
{
varinnerWriter=newBinaryWriter(innerStream);
EncodeIntegerBigEndian(innerWriter,newbyte[]{0x00});// Version
EncodeIntegerBigEndian(innerWriter,parameters.Modulus);
EncodeIntegerBigEndian(innerWriter,parameters.Exponent);
EncodeIntegerBigEndian(innerWriter,parameters.D);
EncodeIntegerBigEndian(innerWriter,parameters.P);
EncodeIntegerBigEndian(innerWriter,parameters.Q);
EncodeIntegerBigEndian(innerWriter,parameters.DP);
EncodeIntegerBigEndian(innerWriter,parameters.DQ);
EncodeIntegerBigEndian(innerWriter,parameters.InverseQ);
varlength=(int)innerStream.Length;
EncodeLength(writer,length);
writer.Write(innerStream.GetBuffer(),0,length);
}
varbase64=Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length).ToCharArray();
outputStream.WriteLine("-----BEGIN RSA PRIVATE KEY-----");
// Output as Base64 with lines chopped at 64 characters
for(vari=0;i<base64.Length;i+=64)
{
outputStream.WriteLine(base64,i,Math.Min(64,base64.Length-i));
}
outputStream.WriteLine("-----END RSA PRIVATE KEY-----");
}
}
privatestaticvoidEncodeIntegerBigEndian(BinaryWriterstream,byte[]value,boolforceUnsigned=true)
{
stream.Write((byte)0x02);// INTEGER
varprefixZeros=0;
for(vari=0;i<value.Length;i++)
{
if(value[i]!=0)break;
prefixZeros++;
}
if(value.Length-prefixZeros==0)
{
EncodeLength(stream,1);
stream.Write((byte)0);
}
else
{
if(forceUnsigned&&value[prefixZeros]>0x7f)
{
// Add a prefix zero to force unsigned if the MSB is 1
EncodeLength(stream,value.Length-prefixZeros+1);
stream.Write((byte)0);
}
else
{
EncodeLength(stream,value.Length-prefixZeros);
}
for(vari=prefixZeros;i<value.Length;i++)
{
stream.Write(value[i]);
}
}
}
privatestaticvoidEncodeLength(BinaryWriterstream,intlength)
{
if(length<0)thrownewArgumentOutOfRangeException("length","Length must be non-negative");
if(length<0x80)
{
// Short form
stream.Write((byte)length);
}
else
{
// Long form
vartemp=length;
varbytesRequired=0;
while(temp>0)
{
temp>>=8;
bytesRequired++;
}
stream.Write((byte)(bytesRequired|0x80));
for(vari=bytesRequired-1;i>=0;i--)
{
stream.Write((byte)(length>>(8*i)&0xff));
}
}
}
}
}