├── AdvSim.Cryptography
├── AdvSim.Cryptography.UnitTest
│ ├── AdvSim.Cryptography.UnitTest.csproj
│ ├── Asymmetric.cs
│ ├── Miscellaneous.cs
│ ├── Symmetric.cs
│ └── WindowsLocal.cs
├── AdvSim.Cryptography.sln
└── AdvSim.Cryptography
│ ├── AdvSim.Cryptography.csproj
│ ├── Asymmetric.cs
│ ├── Miscellaneous.cs
│ ├── Symmetric.cs
│ ├── WindowsLocal.cs
│ └── hCrypto.cs
├── LICENSE.md
└── README.md
/AdvSim.Cryptography/AdvSim.Cryptography.UnitTest/AdvSim.Cryptography.UnitTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | disable
5 | disable
6 |
7 | false
8 |
9 | Library
10 |
11 | net6.0-windows;net452;net471;net462
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography.UnitTest/Asymmetric.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using NUnit.Framework;
4 |
5 | namespace AdvSim.Cryptography.UnitTest
6 | {
7 | public class Asymmetric
8 | {
9 | // Unit test globals
10 | //===================================
11 | private static Byte[] bTestData = Encoding.ASCII.GetBytes("Stones are all changed now in Nine grounds out of ten..");
12 |
13 | // Tests
14 | //===================================
15 |
16 | [Test]
17 | public void Test_RSA()
18 | {
19 | Console.WriteLine("[+] Testing RSA");
20 |
21 | RSA test = new RSA();
22 | Byte[] bPublicKey = test.GetPublicKeyArray();
23 |
24 | Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
25 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
26 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
27 |
28 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
29 | }
30 |
31 | [Test]
32 | public void Test_ECDH()
33 | {
34 | Console.WriteLine("[+] Testing ECDH");
35 | #if NET47_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
36 | ECDH test1 = new ECDH(ECDH.ECCurveType.nistP521);
37 | ECDH test2 = new ECDH(ECDH.ECCurveType.nistP521);
38 | #else
39 | ECDH test1 = new ECDH();
40 | ECDH test2 = new ECDH();
41 | #endif
42 | Byte[] bPublic1 = test1.GetPublicKeyArray();
43 | Byte[] bPublic2 = test2.GetPublicKeyArray();
44 |
45 | test1.DeriveSharedKey(bPublic2);
46 | test2.DeriveSharedKey(bPublic1);
47 |
48 | Byte[] bEncrypted1 = test1.Encrypt(bTestData);
49 | Console.WriteLine(BitConverter.ToString(bEncrypted1).Replace("-", ""));
50 | Byte[] bEncrypted2 = test2.Encrypt(bTestData);
51 |
52 | Assert.That(bEncrypted1, Is.EqualTo(bEncrypted2));
53 | }
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography.UnitTest/Miscellaneous.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NUnit.Framework;
3 |
4 | namespace AdvSim.Cryptography.UnitTest
5 | {
6 | public class Miscellaneous
7 | {
8 | [Test]
9 | public void Test_TOTP()
10 | {
11 | Console.WriteLine("[+] Testing TOTP");
12 |
13 | TOTP test = new TOTP("jumanji");
14 | TOTP.OTP oOTP = test.GenerateTOTP();
15 | TOTP test2 = new TOTP("jumanji");
16 | TOTP.OTP oOTP2 = test2.GenerateTOTP();
17 |
18 | Console.WriteLine("OTP: {0}", oOTP.Code);
19 | Console.WriteLine("Last OTP: {0}", oOTP.LastCode);
20 | Console.WriteLine("Seconds: {0}", oOTP.Seconds);
21 |
22 | Assert.That(oOTP.Code, Is.EqualTo(oOTP2.Code));
23 | }
24 |
25 | [Test]
26 | public void Test_TOTP2()
27 | {
28 | Console.WriteLine("[+] Testing TOTP");
29 |
30 | TOTP test = new TOTP("jumanji");
31 | TOTP.OTP oOTP = test.GenerateTOTP();
32 | TOTP test2 = new TOTP("MarstenHouse");
33 | TOTP.OTP oOTP2 = test2.GenerateTOTP();
34 |
35 | Console.WriteLine("[+] Test 1");
36 | Console.WriteLine("OTP: {0}", oOTP.Code);
37 | Console.WriteLine("Last OTP: {0}", oOTP.LastCode);
38 | Console.WriteLine("Seconds: {0}", oOTP.Seconds);
39 |
40 | Console.WriteLine("[+] Test 2");
41 | Console.WriteLine("OTP: {0}", oOTP2.Code);
42 | Console.WriteLine("Last OTP: {0}", oOTP2.LastCode);
43 | Console.WriteLine("Seconds: {0}", oOTP2.Seconds);
44 |
45 | Assert.That(oOTP.Code, Is.Not.EqualTo(oOTP2.Code));
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography.UnitTest/Symmetric.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using NUnit.Framework;
4 | using AdvSim.Cryptography;
5 |
6 | namespace AdvSim.Cryptography.UnitTest
7 | {
8 | public class Symmetric
9 | {
10 | // Unit test globals
11 | //===================================
12 | private static Byte[] bTestData = Encoding.ASCII.GetBytes("Stones are all changed now in Nine grounds out of ten..");
13 |
14 | // Tests
15 | //===================================
16 |
17 | [Test]
18 | public void Test_AES()
19 | {
20 | Console.WriteLine("[+] Testing AES");
21 |
22 | AES test = new AES("jumanji");
23 | Byte[] bEncrypted = test.Encrypt(bTestData);
24 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
25 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
26 |
27 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
28 | }
29 |
30 | [Test]
31 | public void Test_TDES()
32 | {
33 | Console.WriteLine("[+] Testing TripleDES");
34 |
35 | TripleDES test = new TripleDES("jumanji");
36 | Byte[] bEncrypted = test.Encrypt(bTestData);
37 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
38 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
39 |
40 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
41 | }
42 |
43 | [Test]
44 | public void Test_RC4()
45 | {
46 | Console.WriteLine("[+] Testing RC4");
47 |
48 | RC4 test = new RC4("jumanji");
49 | Byte[] bEncrypted = test.Encrypt(bTestData);
50 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
51 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
52 |
53 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
54 | }
55 |
56 | [Test]
57 | public void Test_RC2()
58 | {
59 | Console.WriteLine("[+] Testing RC2");
60 |
61 | RC2 test = new RC2("jumanji");
62 | Byte[] bEncrypted = test.Encrypt(bTestData);
63 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
64 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
65 |
66 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
67 | }
68 |
69 | [Test]
70 | public void Test_MultiXOR()
71 | {
72 | Console.WriteLine("[+] Testing MultiXOR");
73 |
74 | MultiXOR test = new MultiXOR("jumanji");
75 | Byte[] bEncrypted = test.Encrypt(bTestData);
76 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
77 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
78 |
79 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
80 | }
81 |
82 | [Test]
83 | public void Test_XTEA()
84 | {
85 | Console.WriteLine("[+] Testing XTEA");
86 |
87 | XTEA test = new XTEA("jumanji");
88 | Byte[] bEncrypted = test.Encrypt(bTestData);
89 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
90 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
91 |
92 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
93 | }
94 | }
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography.UnitTest/WindowsLocal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using NUnit.Framework;
4 |
5 | namespace AdvSim.Cryptography.UnitTest
6 | {
7 | public class WindowsLocal
8 | {
9 | // Unit test globals
10 | //===================================
11 | private static Byte[] bTestData = Encoding.ASCII.GetBytes("Stones are all changed now in Nine grounds out of ten..");
12 |
13 | // Tests
14 | //===================================
15 |
16 | #if NETFRAMEWORK
17 | [Test]
18 | public void Test_DPAPI()
19 | {
20 | Console.WriteLine("[+] Testing DPAPI User no entropy");
21 |
22 | DPAPI test = new DPAPI();
23 | Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
24 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
25 | Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
26 |
27 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
28 | }
29 |
30 | [Test]
31 | public void Test_DPAPI_Entropy()
32 | {
33 | Console.WriteLine("[+] Testing DPAPI Machine with entropy");
34 |
35 | DPAPI test = new DPAPI("jumanji");
36 | Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
37 | Console.WriteLine(BitConverter.ToString(bEncrypted).Replace("-", ""));
38 | Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
39 |
40 | Assert.That(bDecrypted, Is.EqualTo(bTestData));
41 | }
42 | #endif
43 | }
44 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.1.32210.238
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvSim.Cryptography", "AdvSim.Cryptography\AdvSim.Cryptography.csproj", "{294FCDD1-369E-4A7A-82C4-68EAA0CC6B24}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvSim.Cryptography.UnitTest", "AdvSim.Cryptography.UnitTest\AdvSim.Cryptography.UnitTest.csproj", "{CDF0A790-9AB2-404F-B188-85DEA22AF2A0}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {294FCDD1-369E-4A7A-82C4-68EAA0CC6B24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {294FCDD1-369E-4A7A-82C4-68EAA0CC6B24}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {294FCDD1-369E-4A7A-82C4-68EAA0CC6B24}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {294FCDD1-369E-4A7A-82C4-68EAA0CC6B24}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {CDF0A790-9AB2-404F-B188-85DEA22AF2A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {CDF0A790-9AB2-404F-B188-85DEA22AF2A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {CDF0A790-9AB2-404F-B188-85DEA22AF2A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {CDF0A790-9AB2-404F-B188-85DEA22AF2A0}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {DAD6C6AB-3FC2-4AF1-9E50-357DD060051B}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/AdvSim.Cryptography.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | Cryptographic Wrapper Library
6 | IBM AdvSim, Ruben Boonen (@FuzzySec)
7 | Copyright © 2023
8 | https://github.com/FuzzySecurity/AdvSim.Cryptography
9 | https://github.com/FuzzySecurity/AdvSim.Cryptography
10 | Cryptography;AES;Triple DES;RC4;RC2;Multi-Byte XOR;XTEA;ECDH;RSA;DPAPI;TOTP
11 | Standard constructor and function name usage. Better compatibility for ECDH. This version has breaking changes with v1.0.0.
12 | A simple and sane wrapper for a number of cryptographic functions in C#. Cryptographic operations include: AES, Triple DES, RC4, RC2, Multi-Byte XOR, XTEA, ECDH, RSA, DPAPI and TOTP.
13 |
14 | git
15 | 7.3
16 | MIT
17 | net35;net40;net452;net47;net6.0;netstandard2.0
18 | 2.0.0
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/Asymmetric.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace AdvSim.Cryptography
8 | {
9 | public class RSA
10 | {
11 | internal static hCrypto.RSA_KEY_MATERIAL KeyMaterial = null;
12 |
13 | ///
14 | /// Convert an RSAParameters public key object to a byte array.
15 | ///
16 | /// Byte[]
17 | public Byte[] GetPublicKeyArray()
18 | {
19 | using (StringWriter sw = new StringWriter())
20 | {
21 | new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters)).Serialize(sw, KeyMaterial.PublicKey);
22 | return System.Text.Encoding.UTF8.GetBytes(sw.ToString());
23 | }
24 | }
25 |
26 | ///
27 | /// Convert a byte array to an RSAParameters key object.
28 | ///
29 | /// RSA key in a byte array format.
30 | /// RSAParameters
31 | internal RSAParameters ConvertArrayToRSAParameters(Byte[] bKeyObject)
32 | {
33 | using (StringReader sr = new StringReader(System.Text.Encoding.UTF8.GetString(bKeyObject)))
34 | {
35 | return (RSAParameters)new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters)).Deserialize(sr);
36 | }
37 | }
38 |
39 | ///
40 | /// Encrypt a byte array using an RSA certificate public key.
41 | ///
42 | /// RSA public key.
43 | /// Byte array which will be encrypted.
44 | /// Byte[]
45 | public Byte[] Encrypt(Byte[] bPublicKey, Byte[] bData)
46 | {
47 | RSACryptoServiceProvider oRSAProvider = new RSACryptoServiceProvider();
48 | RSAParameters oPublicKey = ConvertArrayToRSAParameters(bPublicKey);
49 | oRSAProvider.ImportParameters(oPublicKey);
50 |
51 | return oRSAProvider.Encrypt(bData, false);
52 | }
53 |
54 | ///
55 | /// Decrypt a byte array using an RSA certificate private key.
56 | ///
57 | /// Byte array which will be decrypted.
58 | /// Byte[]
59 | public Byte[] Decrypt(Byte[] bData)
60 | {
61 | RSACryptoServiceProvider oRSAProvider = new RSACryptoServiceProvider();
62 | oRSAProvider.ImportParameters(KeyMaterial.PrivateKey);
63 |
64 | return oRSAProvider.Decrypt(bData, false);
65 | }
66 |
67 | public RSA()
68 | {
69 | KeyMaterial = new hCrypto.RSA_KEY_MATERIAL();
70 | RSACryptoServiceProvider oRSAProvider = new RSACryptoServiceProvider(4096);
71 | KeyMaterial.PrivateKey = oRSAProvider.ExportParameters(true);
72 | KeyMaterial.PublicKey = oRSAProvider.ExportParameters(false);
73 | }
74 | }
75 |
76 | public class ECDH
77 | {
78 | #if NET47_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER // NET47_OR_GREATER
79 | internal static ECDiffieHellman ecdh = null;
80 | internal static ECCurveType Curve;
81 | internal static hCrypto.ECDH_KEY_MATERIAL oKeyMat = new hCrypto.ECDH_KEY_MATERIAL();
82 |
83 | ///
84 | /// ECCurveType enum defining supported elliptic curve cryptography algorithms.
85 | ///
86 | public enum ECCurveType
87 | {
88 | brainpoolP160r1,
89 | brainpoolP160t1,
90 | brainpoolP192r1,
91 | brainpoolP192t1,
92 | brainpoolP224r1,
93 | brainpoolP224t1,
94 | brainpoolP256r1,
95 | brainpoolP256t1,
96 | brainpoolP320r1,
97 | brainpoolP320t1,
98 | brainpoolP384r1,
99 | brainpoolP384t1,
100 | brainpoolP512r1,
101 | brainpoolP512t1,
102 | nistP256,
103 | nistP384,
104 | nistP521
105 | }
106 |
107 | internal ECDiffieHellman ImportPublicParameters(Byte[] bPublicKey)
108 | {
109 | String sPublicKey = Encoding.UTF8.GetString(bPublicKey);
110 | String[] parts = sPublicKey.Split(';');
111 | Byte[] xBytes = Convert.FromBase64String(parts[0]);
112 | Byte[] yBytes = Convert.FromBase64String(parts[1]);
113 |
114 | ECParameters ecParameters = new ECParameters
115 | {
116 | Curve = ECCurve.CreateFromFriendlyName(Enum.GetName(typeof(ECCurveType), Curve)),
117 | Q = new ECPoint { X = xBytes, Y = yBytes }
118 | };
119 |
120 | ECDiffieHellman ecdhParam = ECDiffieHellman.Create();
121 | ecdhParam.ImportParameters(ecParameters);
122 |
123 | return ecdhParam;
124 | }
125 |
126 | ///
127 | /// Retrieve the ECDH public key from an initialized ECDiffieHellman object.
128 | ///
129 | /// Byte[]
130 | public Byte[] GetPublicKeyArray()
131 | {
132 | ECParameters ecParameters = ecdh.ExportParameters(false);
133 | Byte[] xBytes = ecParameters.Q.X;
134 | Byte[] yBytes = ecParameters.Q.Y;
135 | return Encoding.UTF8.GetBytes(Convert.ToBase64String(xBytes) + ";" + Convert.ToBase64String(yBytes));
136 | }
137 |
138 | ///
139 | /// Generate a shared secret Key/IV from an initialized ECDiffieHellmanCng object and a public key.
140 | ///
141 | /// Public key byte array received during client exchange.
142 | public void DeriveSharedKey(Byte[] publicKey)
143 | {
144 | // Convert public key string to ECDiffieHellman public key
145 | ECDiffieHellman ecdhPublicKey = ImportPublicParameters(publicKey);
146 |
147 | // Derive shared secret
148 | Byte[] sharedSecret = ecdh.DeriveKeyMaterial(ecdhPublicKey.PublicKey);
149 | oKeyMat.Key = new Byte[16];
150 | oKeyMat.IV = new Byte[16];
151 |
152 | Array.Copy(sharedSecret, 0, oKeyMat.Key, 0, 16);
153 | Array.Copy(sharedSecret, 16, oKeyMat.IV, 0, 16);
154 | }
155 |
156 | ///
157 | /// Encrypt a byte array using AES with key material derived from an ECDH key exchange.
158 | ///
159 | /// Byte array which will be encrypted.
160 | /// Byte[]
161 | public Byte[] Encrypt(Byte[] bData)
162 | {
163 | using (Aes aes = Aes.Create())
164 | {
165 | aes.Key = oKeyMat.Key;
166 | aes.IV = oKeyMat.IV;
167 |
168 | ICryptoTransform enc = aes.CreateEncryptor(aes.Key, aes.IV);
169 | using (MemoryStream ms = new MemoryStream())
170 | {
171 | using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
172 | {
173 | using (BinaryWriter sw = new BinaryWriter(cs))
174 | {
175 | sw.Write(bData);
176 | }
177 | return ms.ToArray();
178 | }
179 | }
180 | }
181 | }
182 |
183 | ///
184 | /// Decrypt a byte array using AES with key material derived from an ECDH key exchange.
185 | ///
186 | /// Byte array which will be encrypted.
187 | /// Byte[]
188 | public Byte[] Decrypt(Byte[] bData)
189 | {
190 | using (Aes aes = Aes.Create())
191 | {
192 | aes.Key = oKeyMat.Key;
193 | aes.IV = oKeyMat.IV;
194 |
195 | ICryptoTransform dec = aes.CreateDecryptor(aes.Key, aes.IV);
196 | using (MemoryStream ms = new MemoryStream())
197 | {
198 | using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Write))
199 | {
200 | using (BinaryWriter sw = new BinaryWriter(cs))
201 | {
202 | sw.Write(bData);
203 | }
204 | return ms.ToArray();
205 | }
206 | }
207 | }
208 | }
209 |
210 | public ECDH(ECCurveType curveType)
211 | {
212 | Curve = curveType;
213 | ecdh = ECDiffieHellman.Create(ECCurve.CreateFromFriendlyName(Enum.GetName(typeof(ECCurveType), curveType)));
214 | }
215 | #elif NETFRAMEWORK
216 | internal static ECDiffieHellmanCng ecdhCng = null;
217 | internal static hCrypto.ECDH_KEY_MATERIAL oKeyMat = new hCrypto.ECDH_KEY_MATERIAL();
218 |
219 | ///
220 | /// Retrieve the ECDH public key from an initialized ECDiffieHellmanCng object.
221 | ///
222 | /// Byte[]
223 | public Byte[] GetPublicKeyArray()
224 | {
225 | return ecdhCng.PublicKey.ToByteArray();
226 | }
227 |
228 | ///
229 | /// Generate a shared secret Key/IV from an initialized ECDiffieHellmanCng object and a public key.
230 | ///
231 | /// Public key byte array received during client exchange.
232 | public void DeriveSharedKey(Byte[] publicKey)
233 | {
234 | Byte[] sharedSecret = ecdhCng.DeriveKeyMaterial(CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob));
235 |
236 | oKeyMat.Key = new Byte[16];
237 | oKeyMat.IV = new Byte[16];
238 | Array.Copy(sharedSecret, 0, oKeyMat.Key, 0, 16);
239 | Array.Copy(sharedSecret, 16, oKeyMat.IV, 0, 16);
240 | }
241 |
242 | ///
243 | /// Encrypt a byte array using AES with key material derived from an ECDH key exchange.
244 | ///
245 | /// Byte array which will be encrypted.
246 | /// Byte[]
247 | public Byte[] Encrypt(Byte[] bData)
248 | {
249 | using (Aes aes = Aes.Create())
250 | {
251 | aes.Key = oKeyMat.Key;
252 | aes.IV = oKeyMat.IV;
253 |
254 | ICryptoTransform enc = aes.CreateEncryptor(aes.Key, aes.IV);
255 | using (MemoryStream ms = new MemoryStream())
256 | {
257 | using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
258 | {
259 | using (BinaryWriter sw = new BinaryWriter(cs))
260 | {
261 | sw.Write(bData);
262 | }
263 | return ms.ToArray();
264 | }
265 | }
266 | }
267 | }
268 |
269 | ///
270 | /// Decrypt a byte array using AES with key material derived from an ECDH key exchange.
271 | ///
272 | /// Byte array which will be encrypted.
273 | /// Byte[]
274 | public Byte[] Decrypt(Byte[] bData)
275 | {
276 | using (Aes aes = Aes.Create())
277 | {
278 | aes.Key = oKeyMat.Key;
279 | aes.IV = oKeyMat.IV;
280 |
281 | ICryptoTransform dec = aes.CreateDecryptor(aes.Key, aes.IV);
282 | using (MemoryStream ms = new MemoryStream())
283 | {
284 | using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Write))
285 | {
286 | using (BinaryWriter sw = new BinaryWriter(cs))
287 | {
288 | sw.Write(bData);
289 | }
290 | return ms.ToArray();
291 | }
292 | }
293 | }
294 | }
295 |
296 | public ECDH()
297 | {
298 | ecdhCng = new ECDiffieHellmanCng(256);
299 | ecdhCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
300 | ecdhCng.HashAlgorithm = CngAlgorithm.Sha256;
301 | }
302 | #endif
303 | }
304 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/Miscellaneous.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace AdvSim.Cryptography
7 | {
8 | public class TOTP
9 | {
10 | internal static String sSeed = String.Empty;
11 |
12 | ///
13 | /// TOTP object containing properties of the TOTP generator.
14 | ///
15 | public class OTP
16 | {
17 | public UInt32 Seconds;
18 | public UInt32 Code;
19 | public UInt32 LastCode;
20 | }
21 |
22 | // Misc functions
23 | //============================
24 |
25 | ///
26 | /// Generate TOTP object based on manipulating a HMACSHA256 value seeded with UtcNow and a string based seed.
27 | ///
28 | /// String seed used to generate pseudo-random HMACSHA256 value.
29 | /// TOTP
30 | public OTP GenerateTOTP()
31 | {
32 | // Create return object
33 | OTP oTOTP = new OTP();
34 |
35 | // Get DatTime
36 | DateTime dtNow = DateTime.UtcNow;
37 | oTOTP.Seconds = (UInt32)(60 - dtNow.Second);
38 |
39 | // Subtract seconds from current time
40 | dtNow = dtNow.AddSeconds(-dtNow.Second);
41 |
42 | // -= Get Current TOTP Code =-
43 |
44 | // Init HMAC with DateTime key & compute hash with seed value
45 | HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(dtNow.ToString(CultureInfo.InvariantCulture)));
46 | Byte[] bHash = hmac.ComputeHash(Encoding.ASCII.GetBytes(sSeed));
47 |
48 | // Get TOTP
49 | UInt32 iOffset = (UInt32)bHash[bHash.Length - 1] & 0xF;
50 | oTOTP.Code = (UInt32)((bHash[iOffset] & 0x7F) << 24 | (bHash[iOffset + 1] & 0xFF) << 16 | (bHash[iOffset + 2] & 0xFF) << 8 | (bHash[iOffset + 3] & 0xFF) % 1000000);
51 |
52 | // -= Get Last TOTP Code =-
53 |
54 | // Subtract 1 minute
55 | dtNow = dtNow.AddSeconds(-60);
56 |
57 | // Init HMAC with DateTime key & compute hash with seed value
58 | hmac = new HMACSHA256(Encoding.ASCII.GetBytes(dtNow.ToString(CultureInfo.InvariantCulture)));
59 | bHash = hmac.ComputeHash(Encoding.ASCII.GetBytes(sSeed));
60 |
61 | // Get TOTP
62 | iOffset = (UInt32)bHash[bHash.Length - 1] & 0xF;
63 | oTOTP.LastCode = (UInt32)((bHash[iOffset] & 0x7F) << 24 | (bHash[iOffset + 1] & 0xFF) << 16 | (bHash[iOffset + 2] & 0xFF) << 8 | (bHash[iOffset + 3] & 0xFF) % 1000000);
64 |
65 | // Return TOTP
66 | return oTOTP;
67 | }
68 |
69 | ///
70 | /// Validate TOTP code by manipulating a HMACSHA256 value seeded with UtcNow and a string based seed.
71 | ///
72 | /// String seed used to generate pseudo-random HMACSHA256 value.
73 | /// TOTP integer to validate.
74 | /// Allows the previous TOTP code to also be valid.
75 | /// TOTP
76 | public Boolean ValidateTOTP(UInt32 iCode, Boolean bAllowLastCode = false)
77 | {
78 | // Get TOTP
79 | OTP oTOTP = GenerateTOTP();
80 |
81 | // Check if code is valid
82 | if (oTOTP.Code == iCode || (bAllowLastCode && oTOTP.LastCode == iCode))
83 | {
84 | return true;
85 | }
86 |
87 | return false;
88 | }
89 |
90 | public TOTP(String sEntropy)
91 | {
92 | sSeed = sEntropy;
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/Symmetric.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Security.Cryptography;
4 |
5 | namespace AdvSim.Cryptography
6 | {
7 | public class AES
8 | {
9 | internal static Object KeyMaterial = null;
10 |
11 | ///
12 | /// Encrypt byte array to AES byte array.
13 | ///
14 | /// Byte array which will be encrypted.
15 | /// Byte[]
16 | public Byte[] Encrypt(Byte[] bData)
17 | {
18 | using (Aes aes = Aes.Create())
19 | {
20 | aes.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
21 | aes.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
22 |
23 | ICryptoTransform enc = aes.CreateEncryptor(aes.Key, aes.IV);
24 | using (MemoryStream ms = new MemoryStream())
25 | {
26 | using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
27 | {
28 | using (BinaryWriter sw = new BinaryWriter(cs))
29 | {
30 | sw.Write(bData);
31 | }
32 | return ms.ToArray();
33 | }
34 | }
35 | }
36 | }
37 |
38 | ///
39 | /// Decrypt byte array from AES byte array.
40 | ///
41 | /// Byte array which will be decrypted.
42 | /// Byte[]
43 | public Byte[] Decrypt(Byte[] bData)
44 | {
45 | using (Aes aes = Aes.Create())
46 | {
47 | aes.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
48 | aes.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
49 |
50 | ICryptoTransform dec = aes.CreateDecryptor(aes.Key, aes.IV);
51 | using (MemoryStream ms = new MemoryStream())
52 | {
53 | using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Write))
54 | {
55 | using (BinaryWriter sw = new BinaryWriter(cs))
56 | {
57 | sw.Write(bData);
58 | }
59 | return ms.ToArray();
60 | }
61 | }
62 | }
63 | }
64 |
65 | public AES(String sPassword)
66 | {
67 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.AES_CBC);
68 | }
69 | }
70 |
71 | public class TripleDES
72 | {
73 | internal static Object KeyMaterial = null;
74 |
75 | ///
76 | /// Encrypt byte array to Triple DES byte array.
77 | ///
78 | /// Byte array which will be encrypted.
79 | /// Byte[]
80 | public Byte[] Encrypt(Byte[] bData)
81 | {
82 | using (System.Security.Cryptography.TripleDES tdes = System.Security.Cryptography.TripleDES.Create())
83 | {
84 | tdes.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
85 | tdes.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
86 |
87 | ICryptoTransform enc = tdes.CreateEncryptor(tdes.Key, tdes.IV);
88 | using (MemoryStream ms = new MemoryStream())
89 | {
90 | using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
91 | {
92 | using (BinaryWriter sw = new BinaryWriter(cs))
93 | {
94 | sw.Write(bData);
95 | }
96 | return ms.ToArray();
97 | }
98 | }
99 | }
100 | }
101 |
102 | ///
103 | /// Decrypt byte array from Triple DES byte array.
104 | ///
105 | /// Byte array which will be decrypted.
106 | /// Byte[]
107 | public Byte[] Decrypt(Byte[] bData)
108 | {
109 | using (System.Security.Cryptography.TripleDES tdes = System.Security.Cryptography.TripleDES.Create())
110 | {
111 | tdes.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
112 | tdes.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
113 |
114 | ICryptoTransform dec = tdes.CreateDecryptor(tdes.Key, tdes.IV);
115 | using (MemoryStream ms = new MemoryStream())
116 | {
117 | using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Write))
118 | {
119 | using (BinaryWriter sw = new BinaryWriter(cs))
120 | {
121 | sw.Write(bData);
122 | }
123 | return ms.ToArray();
124 | }
125 | }
126 | }
127 | }
128 |
129 | public TripleDES(String sPassword)
130 | {
131 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.TRIPLE_DES);
132 | }
133 | }
134 |
135 | public class RC4
136 | {
137 | internal static Object KeyMaterial = null;
138 |
139 | ///
140 | /// Encrypt byte array to RC4 byte array.
141 | ///
142 | /// Byte array which will be encrypted.
143 | /// Byte[]
144 | public Byte[] Encrypt(Byte[] bData)
145 | {
146 | Int32 a, i, j;
147 | Int32 tmp;
148 |
149 | Int32[] key = new Int32[256];
150 | Int32[] box = new Int32[256];
151 | Byte[] cipher = new Byte[bData.Length];
152 |
153 | for (i = 0; i < 256; i++)
154 | {
155 | key[i] = (KeyMaterial as Byte[])[i % (KeyMaterial as Byte[]).Length];
156 | box[i] = i;
157 | }
158 | for (j = i = 0; i < 256; i++)
159 | {
160 | j = (j + box[i] + key[i]) % 256;
161 | tmp = box[i];
162 | box[i] = box[j];
163 | box[j] = tmp;
164 | }
165 | for (a = j = i = 0; i < bData.Length; i++)
166 | {
167 | a++;
168 | a %= 256;
169 | j += box[a];
170 | j %= 256;
171 | tmp = box[a];
172 | box[a] = box[j];
173 | box[j] = tmp;
174 | Int32 k = box[((box[a] + box[j]) % 256)];
175 | cipher[i] = (Byte)(bData[i] ^ k);
176 | }
177 | return cipher;
178 | }
179 |
180 | ///
181 | /// Decrypt byte array from RC4 byte array.
182 | ///
183 | /// Byte array which will be decrypted.
184 | /// Byte[]
185 | public Byte[] Decrypt(Byte[] bData)
186 | {
187 | return Encrypt(bData);
188 | }
189 |
190 | public RC4(String sPassword)
191 | {
192 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.RC4);
193 | }
194 | }
195 |
196 | public class RC2
197 | {
198 | internal static Object KeyMaterial = null;
199 |
200 | ///
201 | /// Encrypt byte array to RC2 byte array.
202 | ///
203 | /// Byte array which will be encrypted.
204 | /// Byte[]
205 | public Byte[] Encrypt(Byte[] bData)
206 | {
207 | using (System.Security.Cryptography.RC2 rc2 = System.Security.Cryptography.RC2.Create())
208 | {
209 | rc2.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
210 | rc2.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
211 |
212 | ICryptoTransform enc = rc2.CreateEncryptor(rc2.Key, rc2.IV);
213 | using (MemoryStream ms = new MemoryStream())
214 | {
215 | using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
216 | {
217 | using (BinaryWriter sw = new BinaryWriter(cs))
218 | {
219 | sw.Write(bData);
220 | }
221 | return ms.ToArray();
222 | }
223 | }
224 | }
225 | }
226 |
227 | ///
228 | /// Decrypt byte array from RC2 byte array.
229 | ///
230 | /// Byte array which will be decrypted.
231 | /// Byte[]
232 | public Byte[] Decrypt(Byte[] bData)
233 | {
234 | using (System.Security.Cryptography.RC2 rc2 = System.Security.Cryptography.RC2.Create())
235 | {
236 | rc2.Key = (KeyMaterial as hCrypto.KEY_MATERIAL).Key;
237 | rc2.IV = (KeyMaterial as hCrypto.KEY_MATERIAL).IV;
238 |
239 | ICryptoTransform dec = rc2.CreateDecryptor(rc2.Key, rc2.IV);
240 | using (MemoryStream ms = new MemoryStream())
241 | {
242 | using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Write))
243 | {
244 | using (BinaryWriter sw = new BinaryWriter(cs))
245 | {
246 | sw.Write(bData);
247 | }
248 | return ms.ToArray();
249 | }
250 | }
251 | }
252 | }
253 |
254 | public RC2(String sPassword)
255 | {
256 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.RC2);
257 | }
258 | }
259 |
260 | public class MultiXOR
261 | {
262 | internal static Object KeyMaterial = null;
263 |
264 | ///
265 | /// Encrypt byte array using 100-byte XOR key.
266 | ///
267 | /// Byte array which will be encrypted.
268 | /// Byte[]
269 | public Byte[] Encrypt(Byte[] bData)
270 | {
271 | Byte[] bKey = (KeyMaterial as Byte[]);
272 | Byte[] bCipher = new Byte[bData.Length];
273 | for (Int32 i = 0; i < bData.Length; i++)
274 | {
275 | bCipher[i] = (Byte)(bData[i] ^ bKey[i % bKey.Length]);
276 | }
277 | return bCipher;
278 | }
279 |
280 | ///
281 | /// Decrypt byte array using 100-byte XOR key.
282 | ///
283 | /// Byte array which will be decrypted.
284 | /// Byte[]
285 | public Byte[] Decrypt(Byte[] bData)
286 | {
287 | return Encrypt(bData);
288 | }
289 |
290 | public MultiXOR(String sPassword)
291 | {
292 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.MULTI_XOR);
293 | }
294 | }
295 |
296 | public class XTEA
297 | {
298 | internal static Object KeyMaterial = null;
299 |
300 | ///
301 | /// Encrypt byte array to XTEA byte array.
302 | ///
303 | /// Byte array which will be encrypted.
304 | /// Byte[]
305 | public Byte[] Encrypt(Byte[] bData)
306 | {
307 | Byte[] keyBuffer = (KeyMaterial as Byte[]);
308 | UInt32[] blockBuffer = new UInt32[2];
309 | Byte[] result = new Byte[(bData.Length + 4 + 7) / 8 * 8];
310 | Byte[] lengthBuffer = BitConverter.GetBytes(bData.Length);
311 | Array.Copy(lengthBuffer, result, lengthBuffer.Length);
312 | Array.Copy(bData, 0, result, lengthBuffer.Length, bData.Length);
313 | using (MemoryStream stream = new MemoryStream(result))
314 | {
315 | using (BinaryWriter writer = new BinaryWriter(stream))
316 | {
317 | for (Int32 i = 0; i < result.Length; i += 8)
318 | {
319 | blockBuffer[0] = BitConverter.ToUInt32(result, i);
320 | blockBuffer[1] = BitConverter.ToUInt32(result, i + 4);
321 |
322 | UInt32 v0 = blockBuffer[0], v1 = blockBuffer[1], sum = 0, delta = 0x9E3779B9;
323 | for (UInt32 j = 0; j < 32; j++)
324 | {
325 | v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keyBuffer[sum & 3]);
326 | sum += delta;
327 | v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keyBuffer[(sum >> 11) & 3]);
328 | }
329 | blockBuffer[0] = v0;
330 | blockBuffer[1] = v1;
331 |
332 | writer.Write(blockBuffer[0]);
333 | writer.Write(blockBuffer[1]);
334 | }
335 | }
336 | }
337 | return result;
338 | }
339 |
340 | ///
341 | /// Decrypt byte array from XTEA byte array.
342 | ///
343 | /// Byte array which will be decrypted.
344 | /// Byte[]
345 | public Byte[] Decrypt(Byte[] bData)
346 | {
347 | Byte[] keyBuffer = (KeyMaterial as Byte[]);
348 | UInt32[] blockBuffer = new UInt32[2];
349 | Byte[] buffer = new Byte[bData.Length];
350 | Array.Copy(bData, buffer, bData.Length);
351 | using (MemoryStream stream = new MemoryStream(buffer))
352 | {
353 | using (BinaryWriter writer = new BinaryWriter(stream))
354 | {
355 | for (Int32 i = 0; i < buffer.Length; i += 8)
356 | {
357 | blockBuffer[0] = BitConverter.ToUInt32(buffer, i);
358 | blockBuffer[1] = BitConverter.ToUInt32(buffer, i + 4);
359 |
360 | UInt32 v0 = blockBuffer[0], v1 = blockBuffer[1], delta = 0x9E3779B9, sum = delta * 32;
361 | for (UInt32 j = 0; j < 32; j++)
362 | {
363 | v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keyBuffer[(sum >> 11) & 3]);
364 | sum -= delta;
365 | v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keyBuffer[sum & 3]);
366 | }
367 | blockBuffer[0] = v0;
368 | blockBuffer[1] = v1;
369 |
370 | writer.Write(blockBuffer[0]);
371 | writer.Write(blockBuffer[1]);
372 | }
373 | }
374 | }
375 | // verify valid length
376 | UInt32 length = BitConverter.ToUInt32(buffer, 0);
377 | Byte[] result = new Byte[length];
378 | Array.Copy(buffer, 4, result, 0, length);
379 | return result;
380 | }
381 |
382 | public XTEA(String sPassword)
383 | {
384 | KeyMaterial = hCrypto.GenerateKeyMaterial(sPassword, hCrypto.CryptographyType.XTEA);
385 | }
386 | }
387 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/WindowsLocal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace AdvSim.Cryptography
7 | {
8 | #if NETFRAMEWORK
9 | public class DPAPI
10 | {
11 | internal static String sDPAPIEntropy = String.Empty;
12 |
13 | // DPAPI Local Machine
14 | //---------------------
15 |
16 | ///
17 | /// Encrypt a byte array using local machine DPAPI key material.
18 | ///
19 | /// Byte array which will be encrypted.
20 | /// Byte[]
21 | public Byte[] EncryptMachineDPAPI(Byte[] bData)
22 | {
23 | if (!String.IsNullOrEmpty(sDPAPIEntropy))
24 | {
25 | Byte[] bEntropy = hCrypto.GenerateEntropy(sDPAPIEntropy);
26 | return ProtectedData.Protect(bData, bEntropy, DataProtectionScope.LocalMachine);
27 | }
28 |
29 | return ProtectedData.Protect(bData, null, DataProtectionScope.LocalMachine);
30 | }
31 |
32 | ///
33 | /// Decrypt a byte array using local machine DPAPI key material.
34 | ///
35 | /// Byte array which will be decrypted.
36 | /// Byte[]
37 | public Byte[] DecryptMachineDPAPI(Byte[] bData)
38 | {
39 | if (!String.IsNullOrEmpty(sDPAPIEntropy))
40 | {
41 | Byte[] bEntropy = hCrypto.GenerateEntropy(sDPAPIEntropy);
42 | return ProtectedData.Unprotect(bData, bEntropy, DataProtectionScope.LocalMachine);
43 | }
44 |
45 | return ProtectedData.Unprotect(bData, null, DataProtectionScope.LocalMachine);
46 | }
47 |
48 | // DPAPI Current User
49 | //---------------------
50 |
51 | ///
52 | /// Encrypt a byte array using current user DPAPI key material.
53 | ///
54 | /// Byte array which will be encrypted.
55 | /// Byte[]
56 | public Byte[] EncryptUserDPAPI(Byte[] bData)
57 | {
58 | if (!String.IsNullOrEmpty(sDPAPIEntropy))
59 | {
60 | Byte[] bEntropy = hCrypto.GenerateEntropy(sDPAPIEntropy);
61 | return ProtectedData.Protect(bData, bEntropy, DataProtectionScope.CurrentUser);
62 | }
63 |
64 | return ProtectedData.Protect(bData, null, DataProtectionScope.CurrentUser);
65 | }
66 |
67 | ///
68 | /// Decrypt a byte array using current user DPAPI key material.
69 | ///
70 | /// Byte array which will be decrypted.
71 | /// Byte[]
72 | public Byte[] DecryptUserDPAPI(Byte[] bData)
73 | {
74 | if (!String.IsNullOrEmpty(sDPAPIEntropy))
75 | {
76 | Byte[] bEntropy = hCrypto.GenerateEntropy(sDPAPIEntropy);
77 | return ProtectedData.Unprotect(bData, bEntropy, DataProtectionScope.CurrentUser);
78 | }
79 |
80 | return ProtectedData.Unprotect(bData, null, DataProtectionScope.CurrentUser);
81 | }
82 |
83 | public DPAPI(String sEntropy = "")
84 | {
85 | if (!String.IsNullOrEmpty(sEntropy))
86 | {
87 | sDPAPIEntropy = sEntropy;
88 | }
89 | }
90 | }
91 | #endif
92 | }
--------------------------------------------------------------------------------
/AdvSim.Cryptography/AdvSim.Cryptography/hCrypto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace AdvSim.Cryptography
7 | {
8 | public class hCrypto
9 | {
10 | ///
11 | /// ECDH key material containing Key/IV.
12 | ///
13 | internal class ECDH_KEY_MATERIAL
14 | {
15 | public Byte[] Key = null;
16 | public Byte[] IV = null;
17 | }
18 |
19 | ///
20 | /// RSA key material containing certificate public/private keypair.
21 | ///
22 | internal class RSA_KEY_MATERIAL
23 | {
24 | public RSAParameters PublicKey;
25 | public RSAParameters PrivateKey;
26 | }
27 |
28 | ///
29 | /// Generic key material object containing Key/IV.
30 | ///
31 | internal class KEY_MATERIAL
32 | {
33 | public Byte[] Key = null;
34 | public Byte[] IV = null;
35 | }
36 |
37 | ///
38 | /// Enum defining supported symmetric encryption algorithms.
39 | ///
40 | internal enum CryptographyType : UInt16
41 | {
42 | AES_CBC = 0x0001,
43 | TRIPLE_DES = 0x0002,
44 | RC4 = 0x0003,
45 | RC2 = 0x0004,
46 | MULTI_XOR = 0x0005,
47 | XTEA = 0x0006,
48 | }
49 |
50 | ///
51 | /// Generate KeyMaterial from a string. Output depends on the cryptography type selected.
52 | ///
53 | /// String seed used to generate pseudo-random key material.
54 | /// Type of cryptographic key material to initialize.
55 | /// Object
56 | internal static Object GenerateKeyMaterial(String sPassword, CryptographyType eType)
57 | {
58 | // Return object
59 | Object oKeyMaterial = null;
60 |
61 | // Initialize derivation function
62 | // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes?view=net-6.0
63 | Rfc2898DeriveBytes oRfc2898DeriveBytes = new Rfc2898DeriveBytes(Encoding.UTF32.GetBytes(sPassword), Encoding.UTF32.GetBytes(sPassword).Reverse().ToArray(), 20);
64 |
65 | switch (eType)
66 | {
67 | // Set output depending on algorithm
68 | case CryptographyType.AES_CBC:
69 | oKeyMaterial = new KEY_MATERIAL
70 | {
71 | Key = oRfc2898DeriveBytes.GetBytes(32),
72 | IV = oRfc2898DeriveBytes.GetBytes(16)
73 | };
74 | break;
75 | case CryptographyType.RC4:
76 | oKeyMaterial = oRfc2898DeriveBytes.GetBytes(256);
77 | break;
78 | case CryptographyType.MULTI_XOR:
79 | oKeyMaterial = oRfc2898DeriveBytes.GetBytes(100);
80 | break;
81 | case CryptographyType.TRIPLE_DES:
82 | oKeyMaterial = new KEY_MATERIAL
83 | {
84 | Key = oRfc2898DeriveBytes.GetBytes(24),
85 | IV = oRfc2898DeriveBytes.GetBytes(8)
86 | };
87 | break;
88 | case CryptographyType.RC2:
89 | oKeyMaterial = new KEY_MATERIAL
90 | {
91 | Key = oRfc2898DeriveBytes.GetBytes(16),
92 | IV = oRfc2898DeriveBytes.GetBytes(8)
93 | };
94 | break;
95 | case CryptographyType.XTEA:
96 | oKeyMaterial = oRfc2898DeriveBytes.GetBytes(128);
97 | break;
98 | }
99 |
100 | return oKeyMaterial;
101 | }
102 |
103 | ///
104 | /// Generate entropy from a string, optionally specify the amount of entropy returned.
105 | ///
106 | /// String seed used to generate pseudo-random entropy.
107 | /// Amount of bytes to return, defaults to 32.
108 | /// Byte[]
109 | internal static Byte[] GenerateEntropy(String sEntropySeed, UInt32 iLength = 32)
110 | {
111 | // Initialize derivation function
112 | // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes?view=net-6.0
113 | Rfc2898DeriveBytes oRfc2898DeriveBytes = new Rfc2898DeriveBytes(Encoding.UTF32.GetBytes(sEntropySeed), Encoding.UTF32.GetBytes(sEntropySeed).Reverse().ToArray(), 10);
114 |
115 | // Return pseudo-random array
116 | return oRfc2898DeriveBytes.GetBytes((Int32)iLength);
117 | }
118 |
119 | ///
120 | /// Internal function to convert a decimal string to a byte array.
121 | ///
122 | /// Decimal string to convert to byte array
123 | internal static Byte[] DecimalStringToByteArray(String decimalString)
124 | {
125 | Int32 byteCount = (Int32)Math.Ceiling(decimalString.Length * Math.Log10(10) / Math.Log10(256));
126 | Byte[] bytes = new Byte[byteCount];
127 |
128 | foreach (Char c in decimalString)
129 | {
130 | Int32 carry = c - '0';
131 | for (Int32 i = 0; i < bytes.Length; ++i)
132 | {
133 | Int32 value = bytes[i] * 10 + carry;
134 | bytes[i] = (Byte)(value % 256);
135 | carry = value / 256;
136 | }
137 | }
138 |
139 | Array.Reverse(bytes);
140 | return bytes;
141 | }
142 | }
143 | }
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 IBM AdvSim, Ruben Boonen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | # AdvSim.Cryptography
3 |
4 | The `AdvSim.Cryptography` NuGet contains a set of cryptographic wrapper functions which are reusable, configured with sane defaults and are easy to use. Further details are available under the different subheadings below.
5 |
6 | - [Symmetric](#symmetric)
7 | - [Key Material Generation](#key-material-generation)
8 | - [AES](#aes)
9 | - [Triple DES](#triple-des)
10 | - [RC4](#rc4)
11 | - [RC2](#rc2)
12 | - [Multi-Byte XOR](#multi-byte-xor)
13 | - [XTEA](#xtea)
14 | - [Asymmetric](#asymmetric)
15 | - [Elliptic-curve Diffie–Hellman (ECDH)](#elliptic-curve-diffiehellman-ecdh)
16 | - [RSA](#rsa)
17 | - [Windows Local](#windows-local)
18 | - [Entropy Generation](#entropy-generation)
19 | - [DPAPI Local Machine](#dpapi-local-machine)
20 | - [DPAPI Current User](#dpapi-current-user)
21 | - [Miscellaneous](#miscellaneous)
22 | - [TOTP](#totp)
23 |
24 | #### NuGet Compatibility
25 |
26 | The `AdvSim.Cryptography` NuGet supports a wide variety of .Net versions. Generally functions included in the library have good coverage across target frameworks. Where functions are restricted to specific frameworks, a badge has been added to highlight that dependency.
27 |
28 | ***NuGet URL***: https://www.nuget.org/packages/AdvSim.Cryptography
29 |
30 | #### Key Material
31 |
32 | Where key material is provided as part of the cryptographic constructor, `Rfc2898DeriveBytes` is used to return pseudo-random byte arrays to seed the encryption and decryption operations. These byte arrays are high quality while also ensuring that calling the same function with the same key material will result in the same pseudo-random seed.
33 |
34 | # Usage
35 |
36 | ## Symmetric
37 |
38 | #### AES
39 |
40 | 
41 |
42 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
43 |
44 | ```cs
45 | AES test = new AES("Lovecraft");
46 | Byte[] bEncrypted = test.Encrypt(bTestData);
47 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
48 | ```
49 |
50 | #### Triple DES
51 |
52 | 
53 |
54 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
55 |
56 | ```cs
57 | TripleDES test = new TripleDES("Lovecraft");
58 | Byte[] bEncrypted = test.Encrypt(bTestData);
59 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
60 | ```
61 |
62 | #### RC4
63 |
64 | 
65 |
66 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
67 |
68 | ```cs
69 | RC4 test = new RC4("Lovecraft");
70 | Byte[] bEncrypted = test.Encrypt(bTestData);
71 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
72 | ```
73 |
74 | #### RC2
75 |
76 | 
77 |
78 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
79 |
80 | ```cs
81 | RC2 test = new RC2("Lovecraft");
82 | Byte[] bEncrypted = test.Encrypt(bTestData);
83 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
84 | ```
85 |
86 | #### Multi-Byte XOR
87 |
88 | 
89 |
90 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
91 |
92 | ```cs
93 | MultiXOR test = new MultiXOR("Lovecraft");
94 | Byte[] bEncrypted = test.Encrypt(bTestData);
95 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
96 | ```
97 |
98 | #### XTEA
99 |
100 | 
101 |
102 | This function takes a byte array and will either encrypt or decrypt it using the key material provided in the constructor. On completion it will return a byte array.
103 |
104 | ```cs
105 | XTEA test = new XTEA("Lovecraft");
106 | Byte[] bEncrypted = test.Encrypt(bTestData);
107 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
108 | ```
109 |
110 | ## Asymmetric
111 |
112 | ### Elliptic-curve Diffie–Hellman (ECDH)
113 |
114 |  
115 |
116 | Note here that in `v2.0.0` ECDH is supported across all .Net versions available in the NuGet. However, because of some really questionable .Net design decisions it is non-trivial to get interop between all supported targets.
117 |
118 | As a result there are implementation differences between `Framework < .Net 4.7` and everything else. Both clients should fall into the same group to successfully perform a key exchange. If, for example, you need one client to be on `.Net 6` and another on `.Net 4.5.1` then you should use `RSA` instead.
119 |
120 | To understand more about .Net versioning you can consult the following resource.
121 |
122 | - [https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies](https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies)
123 |
124 | #### Usage
125 |
126 | ***Framework < .Net 4.7***
127 |
128 | These targets only support `nistP256` and can use the library as follows.
129 |
130 | ```cs
131 | // Initialize both clients
132 | ECDH test1 = new ECDH();
133 | ECDH test2 = new ECDH();
134 |
135 | // Exchange public keys
136 | Byte[] bPublic1 = test1.GetPublicKeyArray();
137 | Byte[] bPublic2 = test2.GetPublicKeyArray();
138 |
139 | // Derive
140 | test1.DeriveSharedKey(bPublic2);
141 | test2.DeriveSharedKey(bPublic1);
142 |
143 | // Encrypt / Decrypt
144 | Byte[] bEncrypted1 = test1.Encrypt(bTestData);
145 | Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
146 | ```
147 |
148 | ***.Net 4.7+ || Standard 2.1 || .Net 6***
149 |
150 | These targets take a curve as an argument for the constructor.
151 |
152 | ```cs
153 | public enum ECCurveType
154 | {
155 | brainpoolP160r1,
156 | brainpoolP160t1,
157 | brainpoolP192r1,
158 | brainpoolP192t1,
159 | brainpoolP224r1,
160 | brainpoolP224t1,
161 | brainpoolP256r1,
162 | brainpoolP256t1,
163 | brainpoolP320r1,
164 | brainpoolP320t1,
165 | brainpoolP384r1,
166 | brainpoolP384t1,
167 | brainpoolP512r1,
168 | brainpoolP512t1,
169 | nistP256,
170 | nistP384,
171 | nistP521
172 | }
173 | ```
174 |
175 | Usage is shown below.
176 |
177 | ```cs
178 | // Initialize both clients
179 | ECDH test1 = new ECDH(ECDH.ECCurveType.nistP521);
180 | ECDH test2 = new ECDH(ECDH.ECCurveType.nistP521);
181 |
182 | // Exchange public keys
183 | Byte[] bPublic1 = test1.GetPublicKeyArray();
184 | Byte[] bPublic2 = test2.GetPublicKeyArray();
185 |
186 | // Derive
187 | test1.DeriveSharedKey(bPublic2);
188 | test2.DeriveSharedKey(bPublic1);
189 |
190 | // Encrypt / Decrypt
191 | Byte[] bEncrypted1 = test1.Encrypt(bTestData);
192 | Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
193 | ```
194 |
195 | ### RSA
196 |
197 | 
198 |
199 | Note that this functionality does necessarily require two clients since public keys do not have to be exchanged to derive a shared secret as is the case for ECDH. Of course as above you can send your public key on the wire to a different client who can then encrypt data only you can decrypt.
200 |
201 | #### Usage
202 |
203 | ```cs
204 | RSA test = new RSA();
205 | Byte[] bPublicKey = test.GetPublicKeyArray();
206 | Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
207 | Byte[] bDecrypted = test.Decrypt(bEncrypted);
208 | ```
209 |
210 | ## Windows Local
211 |
212 | #### DPAPI Local Machine
213 |
214 | 
215 |
216 | Data that is encrypted and decrypted is scoped to the machine. Data cannot be decrypted off-host.
217 |
218 | ```cs
219 | // Without entropy
220 | DPAPI test = new DPAPI();
221 | Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
222 | Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
223 |
224 | // With entropy
225 | DPAPI test = new DPAPI("Lovecraft");
226 | Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
227 | Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
228 | ```
229 |
230 | #### DPAPI Current User
231 |
232 | 
233 |
234 | Data that is encrypted and decrypted is scoped to the current user. Data cannot be decrypted in a different user context.
235 |
236 | ```cs
237 | // Without entropy
238 | DPAPI test = new DPAPI();
239 | Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
240 | Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
241 |
242 | // With entropy
243 | DPAPI test = new DPAPI("Lovecraft");
244 | Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
245 | Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
246 | ```
247 |
248 | ## Miscellaneous
249 |
250 | ### TOTP
251 |
252 | 
253 |
254 | A time-based one-time password (TOTP) can be used as an additional check when performing actions to validate that they are authentic. TOTP's generated by the library are valid for a full `UtcNow` minute. These numeric secrets can also be used to dynamically seed rotating keys for symmetric encryption algorithms. If clients use the same seed on different machines, they will receive the same TOTP.
255 |
256 | #### Usage
257 |
258 | ```cs
259 | // Generate a TOTP using a string seed
260 | TOTP test = new TOTP("Lovecraft");
261 | Console.WriteLine("[+] TOPT Code : " + oOTP.Code);
262 | Console.WriteLine("[+] TOPT Last Code: " + oOTP.LastCode);
263 | Console.WriteLine("[+] TOPT Validity : " + oOTP.Seconds);
264 |
265 | // Validate TOTP based on string seed
266 | Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.Code);
267 |
268 | // Validate TOTP with forgiveness, this allows the previous TOTP
269 | // to also be counted as valid
270 | Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.LastCode, true);
271 | ```
--------------------------------------------------------------------------------