/// <summary> /// Update session key according to section 5.3.7 Session Key Updates. /// </summary> internal void UpdateSessionKey() { if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { currentClientEncryptKey = UpdateKey(initialClientEncryptKey, currentClientEncryptKey, encryptionMethod); currentClientDecryptKey = UpdateKey(initialClientDecryptKey, currentClientDecryptKey, encryptionMethod); currentServerEncryptKey = UpdateKey(initialServerEncryptKey, currentServerEncryptKey, encryptionMethod); currentServerDecryptKey = UpdateKey(initialServerDecryptKey, currentServerDecryptKey, encryptionMethod); RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider(); rc4Encrypt = rc4Enc.CreateEncryptor(currentClientEncryptKey, null); rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null); RC4CryptoServiceProvider rc4Dec = new RC4CryptoServiceProvider(); rc4Decrypt = rc4Dec.CreateDecryptor(currentClientDecryptKey, null); rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null); } // else in other cases we don't need to update session key }
/// <summary> /// RC4 is used to encrypt and decrypt data according to [MS-RDPELE] 5.1.3 & 5.1.4 /// </summary> private byte[] RC4(byte[] input) { RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider(); ICryptoTransform rc4Encrypt = rc4Enc.CreateEncryptor(licensingEncryptionKey, null); byte[] output = new byte[input.Length]; rc4Encrypt.TransformBlock(input, 0, input.Length, output, 0); return(output); }
/// <summary> /// Compute RC4. /// </summary> /// <param name="key">The key of RC4.</param> /// <param name="data">The data to be computed.</param> /// <returns>The computed result.</returns> internal static byte[] RC4(byte[] key, byte[] data) { var rc4Enc = new RC4CryptoServiceProvider(); var result = new byte[data.Length]; ICryptoTransform rc4Encrypt = rc4Enc.CreateEncryptor(key, null); rc4Encrypt.TransformBlock(data, 0, data.Length, result, 0); return(result); }
/// <summary> /// Update session key for Non-FIPS according to section 5.3.7 Session Key Updates. /// </summary> /// <param name="initialKey">The initial session key.</param> /// <param name="currentKey">The current session key.</param> /// <param name="encryptionMethod">The current encryption method.</param> /// <returns>The new session key.</returns> private static byte[] UpdateKey(byte[] initialKey, byte[] currentKey, EncryptionMethods encryptionMethod) { byte[] pad1 = ConstValue.NON_FIPS_PAD1; byte[] pad2 = ConstValue.NON_FIPS_PAD2; byte[] newKey = null; // SHAComponent = SHA(InitialEncryptKey + Pad1 + CurrentEncryptKey) byte[] shaComponentBuffer = RdpbcgrUtility.ConcatenateArrays(initialKey, pad1, currentKey); byte[] shaComponent = ShaHash(shaComponentBuffer); // TempKey128 = MD5(InitialEncryptKey + Pad2 + SHAComponent) byte[] tempKey128Buffer = RdpbcgrUtility.ConcatenateArrays(initialKey, pad2, shaComponent); byte[] tempKey128 = MD5Hash(tempKey128Buffer); if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { // S-TableEncrypt = InitRC4(TempKey128) RC4CryptoServiceProvider rc4 = new RC4CryptoServiceProvider(); ICryptoTransform ict = rc4.CreateEncryptor(tempKey128, null); // NewEncryptKey128 = RC4(TempKey128, S-TableEncrypt) newKey = ict.TransformFinalBlock(tempKey128, 0, tempKey128.Length); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT) { // TempKey64 = First64Bits(TempKey128) byte[] tempKey64 = GetFirstNBits(64, tempKey128); // S-TableEncrypt = InitRC4(TempKey64) RC4CryptoServiceProvider rc4 = new RC4CryptoServiceProvider(); ICryptoTransform ict = rc4.CreateEncryptor(tempKey64, null); // PreSaltKey = RC4(TempKey64, S-TableEncrypt) byte[] preSaltKey = ict.TransformFinalBlock(tempKey64, 0, tempKey64.Length); if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT) { // NewEncryptKey40 = 0xD1269E + Last40Bits(PreSaltKey) newKey = RdpbcgrUtility.ConcatenateArrays(ConstValue.NON_FIPS_SALT_40BIT, GetLastNBits(40, preSaltKey)); } else { // NewEncryptKey56 = 0xD1 + Last56Bits(PreSaltKey) newKey = RdpbcgrUtility.ConcatenateArrays(ConstValue.NON_FIPS_SALT_56BIT, GetLastNBits(56, preSaltKey)); } } // else do nothing return(newKey); }
static void Main(string[] args) { byte[] key = ComputeTestKey(); byte[] testData = NewTestData(); byte[] jackpozData = testData.ToArray(); byte[] outputBufferBouncy = new byte[1024]; byte[] outputBufferJackpoz = new byte[1024]; JackpozARC4 arc4 = new JackpozARC4(key); RC4CryptoServiceProvider myRc4 = new RC4CryptoServiceProvider(key, true); RC4Engine bouncyRC4 = new RC4Engine(); bouncyRC4.Init(true, new KeyParameter(key)); byte[] sameBuffer = jackpozData.ToArray(); byte[] myRC4Buffer = jackpozData.ToArray(); bouncyRC4.ProcessBytes(testData, 0, testData.Length, outputBufferBouncy, 0); arc4.Process(sameBuffer, sameBuffer, 0, sameBuffer.Length); myRc4.ProcessBytes(myRC4Buffer, 0, myRC4Buffer.Length, myRC4Buffer, 0); Console.WriteLine(jackpozData.Length); for (int i = 0; i < jackpozData.Length; i++) { if (sameBuffer[i] != outputBufferBouncy[i]) { Console.WriteLine($"Failed at index: {i} with Value Jackpoz: {sameBuffer[i]} vs Bouncy: {outputBufferBouncy[i]}"); Console.ReadKey(); } if (myRC4Buffer[i] != outputBufferBouncy[i]) { Console.WriteLine($"Failed at index: {i} with Value MyBuffer: {myRC4Buffer[i]} vs Jackpoz: {sameBuffer[i]}"); Console.ReadKey(); } } Console.WriteLine("Finished parity test."); Stopwatch bouncyWatch = new Stopwatch(); bouncyWatch.Start(); for (int i = 0; i < 1000000; i++) { bouncyRC4.ProcessBytes(testData, 0, testData.Length, outputBufferBouncy, 0); } bouncyWatch.Stop(); GC.Collect(); Console.WriteLine($"Bouncy perf: {bouncyWatch.ElapsedMilliseconds}"); Stopwatch jackpozWatch = new Stopwatch(); jackpozWatch.Start(); for (int i = 0; i < 1000000; i++) { arc4.Process(jackpozData, outputBufferJackpoz, 0, jackpozData.Length); } jackpozWatch.Stop(); GC.Collect(); Console.WriteLine($"Jackpoz perf: {jackpozWatch.ElapsedMilliseconds}"); Console.ReadKey(); }
static void Main(string[] args) { Console.WriteLine("This example shows how to use the symmetric encryption classes from the Security Library.\r\n"); SymmetricAlgorithm algorithm; ICryptoTransform encryptor, decryptor; Console.WriteLine("Select the symmetric algorithm you want to use:"); Console.WriteLine(" [1] ARCFour [managed RC4]"); Console.WriteLine(" [2] RC4 [unmanaged]"); Console.WriteLine(" [3] Rijndael"); Console.Write("Your choice: "); string input = Console.ReadLine().Trim(); // initialize the selected symmetric algorithm switch (input) { case "1": algorithm = new ARCFourManaged(); break; case "2": algorithm = new RC4CryptoServiceProvider(); break; case "3": algorithm = new RijndaelCryptoServiceProvider(); break; default: Console.WriteLine("Invalid input."); return; } Console.WriteLine("Enter some text that will be encrypted:"); input = Console.ReadLine(); byte[] plaintext = Encoding.ASCII.GetBytes(input); // generate an IV that consists of bytes with the value zero // in real life applications, the IV should not be set to // an array of bytes with the value zero! algorithm.IV = new byte[algorithm.BlockSize / 8]; // generate a new key algorithm.GenerateKey(); // create the encryption and decryption objects encryptor = algorithm.CreateEncryptor(); decryptor = algorithm.CreateDecryptor(); // encrypt the bytes byte[] encrypted = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length); // decrypt the encrypted bytes byte[] decrypted = decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length); // write the byte arrays to the console Console.WriteLine("\r\nResults:"); Console.WriteLine(" Input data: " + Encoding.ASCII.GetString(plaintext)); Console.WriteLine(" Key: " + BytesToHex(algorithm.Key)); Console.WriteLine(" Encrypted data: " + BytesToHex(encrypted)); Console.WriteLine(" Decrypted data: " + Encoding.ASCII.GetString(decrypted)); Console.WriteLine("\r\nPress ENTER to continue..."); Console.ReadLine(); // dispose of the resources algorithm.Clear(); encryptor.Dispose(); decryptor.Dispose(); }
private static RC4CryptoServiceProvider GetServiceProvider() { var provider = new RC4CryptoServiceProvider(); return provider; }
internal void GenerateSessionKey(byte[] clientRandom, byte[] serverRandom) { if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { byte[] mackey = null; byte[] clientEncKey = null; byte[] clientDecKey = null; GenerateNonFIPSSessionKey(clientRandom, serverRandom, out mackey, out clientEncKey, out clientDecKey); if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT) { // MACKey40 = 0xD1269E + Last40Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_40BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(40, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(40, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(40, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT) { // MACKey56 = 0xD1 + Last56Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_56BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(56, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(56, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(56, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else // encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT { macKey = mackey; currentClientEncryptKey = clientEncKey; currentServerDecryptKey = clientEncKey; currentClientDecryptKey = clientDecKey; currentServerEncryptKey = clientDecKey; } initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerEncryptKey = currentServerEncryptKey; initialServerDecryptKey = currentServerDecryptKey; RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider(); rc4Encrypt = rc4Enc.CreateEncryptor(currentClientEncryptKey, null); rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null); RC4CryptoServiceProvider rc4Dec = new RC4CryptoServiceProvider(); rc4Decrypt = rc4Dec.CreateDecryptor(currentClientDecryptKey, null); rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS) { GenerateFIPSSessionKey(clientRandom, serverRandom, out macKey, out currentClientEncryptKey, out currentClientDecryptKey, out currentServerEncryptKey, out currentServerDecryptKey); initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerDecryptKey = currentServerDecryptKey; initialServerEncryptKey = currentServerEncryptKey; // suppress "CA5353:TripleDESCannotBeUsed" message, since TripleDES is used according protocol definition in MS-RDPBCGR desEncrypt = new TripleDESCryptoServiceProvider(); desEncrypt.IV = ConstValue.TRPLE_DES_IV; desEncrypt.Key = currentClientEncryptKey; desEncrypt.Mode = CipherMode.CBC; desDecrypt = new TripleDESCryptoServiceProvider(); desDecrypt.IV = ConstValue.TRPLE_DES_IV; desDecrypt.Key = currentClientDecryptKey; desDecrypt.Mode = CipherMode.CBC; desEncryptServer = new TripleDESCryptoServiceProvider(); desEncryptServer.IV = ConstValue.TRPLE_DES_IV; desEncryptServer.Key = currentServerEncryptKey; desEncryptServer.Mode = CipherMode.CBC; desDecryptServer = new TripleDESCryptoServiceProvider(); desDecryptServer.IV = ConstValue.TRPLE_DES_IV; desDecryptServer.Key = currentServerDecryptKey; desDecryptServer.Mode = CipherMode.CBC; } else // the encryption method is ENCRYPTION_METHOD_NONE or error { macKey = null; initialClientEncryptKey = null; initialClientDecryptKey = null; currentClientEncryptKey = null; currentClientDecryptKey = null; initialServerEncryptKey = null; initialServerDecryptKey = null; currentServerEncryptKey = null; currentServerDecryptKey = null; rc4Encrypt = null; rc4Decrypt = null; rc4EncryptServer = null; rc4DecryptServer = null; desEncrypt = null; desDecrypt = null; desEncryptServer = null; desDecryptServer = null; } // the cumulative encryption/decryption count // indicating how many encryptions/decryptions have been carried out. encryptionCount = 0; // the first encryption start with 0 decryptionCount = -1; // after the first decryption, decryptionCount++ up to 0 }