/// <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
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #5
0
        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();
        }
Пример #6
0
    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
        }