-
Notifications
You must be signed in to change notification settings - Fork 2
/
Program.cs
143 lines (123 loc) · 5.27 KB
/
Program.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace InMemoryX509Certificate
{
static class Program
{
static void Main(string[] args)
{
try
{
if (args.Length == 0)
{
Console.WriteLine("Usage: InMemoryX509Certificate.exe [pfxFile] [password]");
return;
}
var pfx = args[0];
var pwd = args.Length > 1 ? args[1] : $"{pfx}.txt";
if (File.Exists(pwd))
{
pwd = File.ReadAllText(pwd);
}
pwd = pwd.Trim();
using (var fileCert = new X509Certificate2(pfx, pwd))
using (var inmem = new InMemoryX509Certificate(pfx, pwd))
using (var memCert = new X509Certificate2(inmem.Handle))
{
EncryptionTests(fileCert, memCert);
SigningTests(fileCert, memCert);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static void EncryptionTests(X509Certificate2 fileCert, X509Certificate2 memCert)
{
var rnd = new Random();
var rawData = new byte[64];
rnd.NextBytes(rawData);
using (var fileCertPrivateKey = fileCert.GetRSAPrivateKey())
using (var memCertPrivateKey = memCert.GetRSAPrivateKey())
using (var fileCertPublicKey = fileCert.GetRSAPublicKey())
using (var memCertPublicKey = memCert.GetRSAPublicKey())
{
var padding = RSAEncryptionPadding.OaepSHA1;
var encryptedUsingFileCert = fileCertPublicKey.Encrypt(rawData, padding);
var encryptedUsingMemoryCert = memCertPublicKey.Encrypt(rawData, padding);
var decryptedUsingFileCert = fileCertPrivateKey.Decrypt(encryptedUsingFileCert, padding);
var decryptedUsingMemoryCert = memCertPrivateKey.Decrypt(encryptedUsingFileCert, padding);
var decryptedUsingFileCert1 = fileCertPrivateKey.Decrypt(encryptedUsingMemoryCert, padding);
var decryptedUsingMemoryCert1 = memCertPrivateKey.Decrypt(encryptedUsingMemoryCert, padding);
// Assert
AssertAreEqual(rawData, decryptedUsingFileCert);
AssertAreEqual(rawData, decryptedUsingMemoryCert);
AssertAreEqual(rawData, decryptedUsingFileCert1);
AssertAreEqual(rawData, decryptedUsingMemoryCert1);
}
Console.WriteLine($"EncryptionTests passed");
}
static void SigningTests(X509Certificate2 fileCert, X509Certificate2 memCert)
{
var rnd = new Random();
var rawData = new byte[256];
rnd.NextBytes(rawData);
using (var fileCertPrivateKey = fileCert.GetRSAPrivateKey())
using (var memCertPrivateKey = memCert.GetRSAPrivateKey())
using (var fileCertPublicKey = fileCert.GetRSAPublicKey())
using (var memCertPublicKey = memCert.GetRSAPublicKey())
{
var signatureUsingFileCert = fileCertPrivateKey.HashAndSign(rawData);
var signatureUsingMemoryCert = memCertPrivateKey.HashAndSign(rawData);
// Assert
fileCertPublicKey.HashAndVerifySignature(rawData, signatureUsingFileCert);
fileCertPublicKey.HashAndVerifySignature(rawData, signatureUsingMemoryCert);
memCertPublicKey.HashAndVerifySignature(rawData, signatureUsingFileCert);
memCertPublicKey.HashAndVerifySignature(rawData, signatureUsingMemoryCert);
}
Console.WriteLine($"SigningTests passed");
}
static byte[] HashAndSign(this RSA rsa, byte[] rawData)
{
using (var hash = new SHA1Managed())
{
byte[] hashedData;
hashedData = hash.ComputeHash(rawData);
return rsa.SignHash(hashedData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
}
static void HashAndVerifySignature(this RSA rsa, byte[] rawData, byte[] signature)
{
using (var hash = new SHA1Managed())
{
byte[] hashedData;
hashedData = hash.ComputeHash(rawData);
if (!rsa.VerifyHash(hashedData, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1))
{
throw new Exception($"Fail verify signature");
}
}
}
static void AssertAreEqual(byte[] src, byte[] dst)
{
if (src.Length == 0)
{
throw new Exception($"Invalid zero length");
}
if (src.Length != dst.Length)
{
throw new Exception($"Length not equals {src.Length} != {dst.Length}");
}
for (int i = 0; i < src.Length; ++i)
{
if (src[i] != dst[i])
{
throw new Exception($"Byte[{i}] not equals {src[i]} != {dst[i]}");
}
}
}
}
}