-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCrypt.cs
117 lines (99 loc) · 3.71 KB
/
Crypt.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
using System.Security.Cryptography;
using System.Text;
namespace ftw_msgr.Crypto;
/// <summary>
/// This unit was the original encryption library using DHKE and AES
/// </summary>
public class Crypt
{
private ECDiffieHellman localKey;
private ECDiffieHellmanPublicKey localPublicKey;
public ECPoint localPublicKey_Q;
public ECDiffieHellmanPublicKey? remotePublicKey { get; set; }
public Crypt()
{
localKey = ECDiffieHellman.Create();
localPublicKey = localKey.PublicKey;
localPublicKey_Q = localPublicKey.ExportParameters().Q;
}
public string DecryptMessage(string ciphertext)
{
byte[] data = System.Convert.FromBase64String(ciphertext);
byte[] rawData;
using Aes aes = AesCng.Create();
int ivLength = aes.BlockSize >> 3;
byte[] ivData = new byte[ivLength];
Array.Copy(data, ivData, ivLength);
if (remotePublicKey is not null)
{
byte[] sumKey = localKey.DeriveKeyMaterial(remotePublicKey);
aes.Key = sumKey;
aes.IV = ivData;
using ICryptoTransform decryptor = aes.CreateDecryptor();
using MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
cs.Write(data, ivLength, data.Length - ivLength);
cs.Close();
rawData = ms.ToArray();
return Encoding.UTF8.GetString(rawData);
}
else
{
return $"Unable to decrypt: {ciphertext} .\n No remote public key found.";
}
}
public T? EncryptMessage<T>(T rawMessage)
{
if (remotePublicKey is not null)
{
byte[] sumKey = localKey.DeriveKeyMaterial(remotePublicKey);
using Aes aes = AesCng.Create();
aes.Key = sumKey;
aes.GenerateIV();
using ICryptoTransform encryptor = aes.CreateEncryptor();
using MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
if (typeof(T) == typeof(string))
{
string? message = rawMessage as string;
if (message is null) { message = ""; }
byte[] rawData = Encoding.UTF8.GetBytes(message);
ms.Write(aes.IV, 0, aes.IV.Length);
cs.Write(rawData, 0, rawData.Length);
cs.Close();
byte[] data = ms.ToArray();
return (T?)Convert.ChangeType(Convert.ToBase64String(data), typeof(T));
}
else if (typeof(T) == typeof(byte[]))
{
char[]? chars = rawMessage as char[];
if (chars is null) { chars = Array.Empty<char>(); }
byte[] rawData = Encoding.UTF8.GetBytes(chars);
ms.Write(aes.IV, 0, aes.IV.Length);
cs.Write(rawData, 0, rawData.Length);
cs.Close();
byte[]? myBytes = ms.ToArray();
char[]? myChars = new char[myBytes.Length];
Convert.ToBase64CharArray(myBytes, 0, myBytes.Length, myChars, 0);
return (T?)Convert.ChangeType(myChars, typeof(T));
}
else
{
return default;
}
}
else
{
return default;
}
}
public void InitRemotePublicKey(ECPoint myQ)
{
ECDiffieHellman ecdh = ECDiffieHellman.Create();
ECParameters myECParams = new() { Q = myQ };
ECCurve curve = localKey.ExportParameters(false).Curve;
myECParams.Curve = curve;
ecdh.ImportParameters(myECParams);
remotePublicKey = ecdh.PublicKey;
}
}