├── 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 | ![Release](https://badgen.net/badge/AdvSim.Cryptography/v2.0.0/cyan?icon=github) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/NETFRAMEWORK%20%3C%20NET47/green) ![Availability](https://badgen.net/badge/Availability/NET47_OR_GREATER%20%7C%7C%20NETSTANDARD2_1_OR_GREATER%20%7C%7C%20NET6_0_OR_GREATER/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ![Availability](https://badgen.net/badge/Availability/NETFRAMEWORK/green) 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 | ![Availability](https://badgen.net/badge/Availability/NETFRAMEWORK/green) 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 | ![Availability](https://badgen.net/badge/Availability/All/green) 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 | ``` --------------------------------------------------------------------------------