/// <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);

                RC4 rc4Enc = RC4.Create();
                rc4Encrypt       = rc4Enc.CreateEncryptor(currentClientEncryptKey, null);
                rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null);

                RC4 rc4Dec = RC4.Create();
                rc4Decrypt       = rc4Dec.CreateDecryptor(currentClientDecryptKey, null);
                rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null);
            }
            // else in other cases we don't need to update session key
        }
Ejemplo n.º 2
0
        protected int TestDecryption()
        {
            int tests            = 0;
            RC4 rc4              = GetRC4Instance();
            ICryptoTransform enc = null;

            byte[] ret = null;
            // test TransformBlock
            for (int i = 0; i < keys.Length; i++)
            {
                try {
                    enc = rc4.CreateDecryptor(keys[i], null);
                } catch {
                    AddError("RC4-TD1");
                }
                try {
                    ret = new byte[outputs[i].Length];
                    enc.TransformBlock(outputs[i], 0, outputs[i].Length, ret, 0);
                } catch {
                    AddError("RC4-TD2");
                }
                if (!ArrayEquals(ret, inputs[i]))
                {
                    AddError("RC4-TD3");
                }
                if (enc != null)
                {
                    enc.Dispose();
                }
                tests += 3;
            }
            // test TransformFinalBlock
            for (int i = 0; i < keys.Length; i++)
            {
                try {
                    enc = rc4.CreateDecryptor(keys[i], null);
                } catch {
                    AddError("RC4-TD4");
                }
                try {
                    ret = enc.TransformFinalBlock(outputs[i], 0, outputs[i].Length);
                } catch {
                    AddError("RC4-TD5");
                }
                if (!ArrayEquals(ret, inputs[i]))
                {
                    AddError("RC4-TD6");
                }
                if (enc != null)
                {
                    enc.Dispose();
                }
                tests += 3;
            }
            return(tests);
        }
Ejemplo n.º 3
0
        public void TestArgumentExceptions()
        {
            using (var rc4 = new RC4()) {
                var buffer = new byte[16];

                Assert.AreEqual(1, rc4.InputBlockSize, "InputBlockSize");
                Assert.AreEqual(1, rc4.OutputBlockSize, "OutputBlockSize");
                Assert.IsFalse(rc4.CanReuseTransform, "CanReuseTransform");
                Assert.IsTrue(rc4.CanTransformMultipleBlocks, "CanTransformMultipleBlocks");

                Assert.Throws <InvalidOperationException> (() => { var x = rc4.Key; });
                Assert.Throws <ArgumentNullException> (() => { rc4.Key = null; });
                Assert.Throws <ArgumentException> (() => { rc4.Key = new byte[0]; });

                rc4.GenerateIV();
                rc4.GenerateKey();
                rc4.CreateDecryptor();
                rc4.CreateEncryptor();

                // TransformBlock input buffer parameters
                Assert.Throws <ArgumentNullException> (() => rc4.TransformBlock(null, 0, buffer.Length, buffer, 0));
                Assert.Throws <ArgumentOutOfRangeException> (() => rc4.TransformBlock(buffer, -1, buffer.Length, buffer, 0));
                Assert.Throws <ArgumentOutOfRangeException> (() => rc4.TransformBlock(buffer, 0, -1, buffer, 0));

                // TransformBlock output buffer parameters
                Assert.Throws <ArgumentNullException> (() => rc4.TransformBlock(buffer, 0, buffer.Length, null, 0));
                Assert.Throws <ArgumentOutOfRangeException> (() => rc4.TransformBlock(buffer, 0, buffer.Length, buffer, -1));

                // TransformFinalBlock
                Assert.Throws <ArgumentNullException> (() => rc4.TransformFinalBlock(null, 0, buffer.Length));
                Assert.Throws <ArgumentOutOfRangeException> (() => rc4.TransformFinalBlock(buffer, -1, buffer.Length));
                Assert.Throws <ArgumentOutOfRangeException> (() => rc4.TransformFinalBlock(buffer, 0, -1));
            }
        }
Ejemplo n.º 4
0
        private bool Decode(byte[] pvk, string password)
        {
            if (BitConverterLE.ToUInt32(pvk, 0) != 2964713758u)
            {
                return(false);
            }
            if (BitConverterLE.ToUInt32(pvk, 4) != 0u)
            {
                return(false);
            }
            this.keyType   = BitConverterLE.ToInt32(pvk, 8);
            this.encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1u);
            int num  = BitConverterLE.ToInt32(pvk, 16);
            int num2 = BitConverterLE.ToInt32(pvk, 20);

            byte[] array = new byte[num2];
            Buffer.BlockCopy(pvk, 24 + num, array, 0, num2);
            if (num > 0)
            {
                if (password == null)
                {
                    return(false);
                }
                byte[] array2 = new byte[num];
                Buffer.BlockCopy(pvk, 24, array2, 0, num);
                byte[]           array3          = this.DeriveKey(array2, password);
                RC4              rc              = RC4.Create();
                ICryptoTransform cryptoTransform = rc.CreateDecryptor(array3, null);
                cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                try
                {
                    this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(array);
                    this.weak = false;
                }
                catch (CryptographicException)
                {
                    this.weak = true;
                    Buffer.BlockCopy(pvk, 24 + num, array, 0, num2);
                    Array.Clear(array3, 5, 11);
                    RC4 rc2 = RC4.Create();
                    cryptoTransform = rc2.CreateDecryptor(array3, null);
                    cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                    this.rsa = CryptoConvert.FromCapiPrivateKeyBlob(array);
                }
                Array.Clear(array3, 0, array3.Length);
            }
            else
            {
                this.weak = true;
                this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(array);
                Array.Clear(array, 0, array.Length);
            }
            Array.Clear(pvk, 0, pvk.Length);
            return(this.rsa != null);
        }
Ejemplo n.º 5
0
        public override void Init(int mode, Key keyspec)
        {
            SecretKeySpec key = (SecretKeySpec)keyspec;

            if (mode == Cipher.ENCRYPT_MODE)
            {
                transformer = rc4.CreateEncryptor(key.Key, new byte[0]);
            }
            else
            {
                transformer = rc4.CreateDecryptor(key.Key, new byte[0]);
            }
        }
Ejemplo n.º 6
0
    // =========================加密相关===================================
    // 加密通讯
    public void Encrypt(Int32 send_seed, Int32 receive_seed)
    {
        Byte[] _send = BitConverter.GetBytes(send_seed);
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(_send);
        }
        Byte[] _recv = BitConverter.GetBytes(receive_seed);
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(_recv);
        }
        string key1;
        string key2;

        Byte[]     _key1 = dhEnc.DecryptKeyExchange(_send);
        BigInteger bi1   = new BigInteger(_key1);

        key1 = Config.SALT + bi1.ToString();

        Byte[]     _key2 = dhDec.DecryptKeyExchange(_recv);
        BigInteger bi2   = new BigInteger(_key2);

        key2 = Config.SALT + bi2.ToString();

        RC4 rc4enc = RC4.Create();
        RC4 rc4dec = RC4.Create();

        Byte[] seed1 = Encoding.ASCII.GetBytes(key1);
        Byte[] seed2 = Encoding.ASCII.GetBytes(key2);

        // en/decryptor不为null时自动启动加密

        // Get an encryptor.
        encryptor = rc4enc.CreateEncryptor(seed1, null);
        // Get a decryptor.
        decryptor = rc4dec.CreateDecryptor(seed2, null);
    }
        private bool Decode(byte[] pvk, string password)
        {
            // DWORD magic
            if (BitConverterLE.ToUInt32(pvk, 0) != magic)
            {
                return(false);
            }
            // DWORD reserved
            if (BitConverterLE.ToUInt32(pvk, 4) != 0x0)
            {
                return(false);
            }
            // DWORD keytype
            keyType = BitConverterLE.ToInt32(pvk, 8);
            // DWORD encrypted
            encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1);
            // DWORD saltlen
            int saltlen = BitConverterLE.ToInt32(pvk, 16);
            // DWORD keylen
            int keylen = BitConverterLE.ToInt32(pvk, 20);

            byte[] keypair = new byte [keylen];
            Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
            // read salt (if present)
            if (saltlen > 0)
            {
                if (password == null)
                {
                    return(false);
                }

                byte[] salt = new byte [saltlen];
                Buffer.BlockCopy(pvk, 24, salt, 0, saltlen);
                // first try with full (128) bits
                byte[] key = DeriveKey(salt, password);
                // decrypt in place and try this
                RC4 rc4 = RC4.Create();
                ICryptoTransform dec = rc4.CreateDecryptor(key, null);
                dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                try
                {
                    rsa  = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                    weak = false;
                }
                catch (CryptographicException)
                {
                    weak = true;
                    // second chance using weak crypto
                    Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
                    // truncate the key to 40 bits
                    Array.Clear(key, 5, 11);
                    // decrypt
                    RC4 rc4b = RC4.Create();
                    dec = rc4b.CreateDecryptor(key, null);
                    dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                    rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                }
                Array.Clear(key, 0, key.Length);
            }
            else
            {
                weak = true;
                // read unencrypted keypair
                rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                Array.Clear(keypair, 0, keypair.Length);
            }

            // zeroize pvk (which could contain the unencrypted private key)
            Array.Clear(pvk, 0, pvk.Length);

            return(rsa != null);
        }
        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;
                RC4 rc4Enc = RC4.Create();
                rc4Encrypt       = rc4Enc.CreateEncryptor(currentClientEncryptKey, null);
                rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null);
                RC4 rc4Dec = RC4.Create();
                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
        }