/// <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
        }
        public static _LSAPR_TRUSTED_DOMAIN_AUTH_BLOB CreateTrustedDomainAuthorizedBlob(
            _LSAPR_AUTH_INFORMATION[] currentOutgoingAuthInfos,
            _LSAPR_AUTH_INFORMATION[] previousOutgoingAuthInfos,
            _LSAPR_AUTH_INFORMATION[] currentIncomingAuthInfos,
            _LSAPR_AUTH_INFORMATION[] previousIncomingAuthInfos,
            byte[] sessionKey)
        {
            _LSAPR_TRUSTED_DOMAIN_AUTH_BLOB retVal = new _LSAPR_TRUSTED_DOMAIN_AUTH_BLOB();
            LsaTrustedDomainAuthBlob        blob   = new LsaTrustedDomainAuthBlob();
            Random random = new Random();

            blob.randomData = new byte[BLOB_AUTH_RANDOM_LENGTH]; //leads with 512 bytes of random data
            random.NextBytes(blob.randomData);
            blob.CurrentOutgoingAuthInfos  = MarshalAuthInfos(currentOutgoingAuthInfos);
            blob.PreviousOutgoingAuthInfos = MarshalAuthInfos(previousOutgoingAuthInfos);
            blob.CurrentIncomingAuthInfos  = MarshalAuthInfos(currentIncomingAuthInfos);
            blob.PreviousIncomingAuthInfos = MarshalAuthInfos(previousIncomingAuthInfos);

            blob.CountOutgoingAuthInfos = (uint)(currentOutgoingAuthInfos == null ? 0 : currentOutgoingAuthInfos.Length);
            //blob.ByteOffsetCurrentOutgoingAuthInfo is the sum of sizeof CountOutgoingAuthInfos,
            //sizeof ByteOffsetCurrentOutgoingAuthInfo ,sizeof ByteOffsetCurrentOutgoingAuthInfo;
            blob.ByteOffsetCurrentOutgoingAuthInfo = (uint)(Marshal.SizeOf(blob.CountOutgoingAuthInfos) + Marshal.SizeOf(
                                                                blob.ByteOffsetCurrentOutgoingAuthInfo) + Marshal.SizeOf(blob.ByteOffsetPreviousOutgoingAuthInfo));
            blob.ByteOffsetPreviousOutgoingAuthInfo = (uint)(blob.ByteOffsetCurrentOutgoingAuthInfo
                                                             + blob.CurrentOutgoingAuthInfos.Length);
            blob.CountIncomingAuthInfos = (uint)(currentIncomingAuthInfos == null ? 0 : currentIncomingAuthInfos.Length);
            //same as blob.ByteOffsetCurrentOutgoingAuthInfo
            blob.ByteOffsetCurrentIncomingAuthInfo = (uint)(Marshal.SizeOf(blob.CountIncomingAuthInfos) + Marshal.SizeOf(
                                                                blob.ByteOffsetCurrentIncomingAuthInfo) + Marshal.SizeOf(blob.ByteOffsetPreviousIncomingAuthInfo));
            blob.ByteOffsetPreviousIncomingAuthInfo = (uint)(blob.ByteOffsetCurrentIncomingAuthInfo
                                                             + blob.CurrentIncomingAuthInfos.Length);
            blob.OutgoingAuthInfoSize = (uint)(blob.ByteOffsetPreviousOutgoingAuthInfo
                                               + blob.PreviousOutgoingAuthInfos.Length);
            blob.IncomingAuthInfoSize = (uint)(blob.ByteOffsetPreviousIncomingAuthInfo
                                               + blob.PreviousIncomingAuthInfos.Length);

            byte[] input = ArrayUtility.ConcatenateArrays(
                blob.randomData,
                TypeMarshal.ToBytes(blob.CountOutgoingAuthInfos),
                TypeMarshal.ToBytes(blob.ByteOffsetCurrentOutgoingAuthInfo),
                TypeMarshal.ToBytes(blob.ByteOffsetPreviousOutgoingAuthInfo),
                blob.CurrentOutgoingAuthInfos,
                blob.PreviousOutgoingAuthInfos,
                TypeMarshal.ToBytes(blob.CountIncomingAuthInfos),
                TypeMarshal.ToBytes(blob.ByteOffsetCurrentIncomingAuthInfo),
                TypeMarshal.ToBytes(blob.ByteOffsetPreviousIncomingAuthInfo),
                blob.CurrentIncomingAuthInfos,
                blob.PreviousIncomingAuthInfos,
                TypeMarshal.ToBytes(blob.OutgoingAuthInfoSize),
                TypeMarshal.ToBytes(blob.IncomingAuthInfoSize));

            using (RC4 rc4 = RC4.Create())
            {
                rc4.Key         = sessionKey;
                retVal.AuthBlob = rc4.CreateEncryptor().TransformFinalBlock(input, 0, input.Length);
            }
            retVal.AuthSize = (uint)(retVal.AuthBlob.Length);

            return(retVal);
        }
        /// <summary>
        /// Encrypts input data with RC4
        /// </summary>
        /// <param name="input">The input data to be encrypted</param>
        /// <param name="inputOffset">Offset of input from which the data will be encrypted </param>
        /// <param name="inputLength">Length of data to be encrypted</param>
        /// <param name="key">The encryption key</param>
        private static byte[] RC4Encrypt(byte[] input, int inputOffset, int inputLength, byte[] key)
        {
            RC4 rc4 = RC4.Create();
            ICryptoTransform crypto = rc4.CreateEncryptor(key, null);

            byte[] output = crypto.TransformFinalBlock(input, inputOffset, inputLength);

            return(output);
        }
Exemple #4
0
 /// <summary>
 /// An example of encryption/decryption from one file to another.
 /// </summary>
 /// <param name="key">The secret key to use for the algorithm.</param>
 /// <param name="sourcePath">File path to read.</param>
 /// <param name="targetPath">File path to write.</param>
 public static void EncoderWrite(byte[] key, string sourcePath, string targetPath)
 {
     using (var rc4 = RC4.Create())
         using (var source = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
             using (var target = new FileStream(targetPath, FileMode.Create, FileAccess.ReadWrite))
                 using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 {
                     crypto.CopyTo(target);
                 }
 }
Exemple #5
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);
        }
Exemple #6
0
 /// <summary>
 /// An example of encryption/decryption from byte array to another
 /// </summary>
 /// <param name="key"></param>
 /// <param name="sourceArray"></param>
 /// <returns></returns>
 public static byte[] EncoderRead(byte[] key, byte[] sourceArray)
 {
     using (var rc4 = RC4.Create())
         using (var source = new MemoryStream(sourceArray))
             using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 using (var target = new MemoryStream())
                 {
                     crypto.CopyTo(target);
                     return(target.ToArray());
                 }
 }
Exemple #7
0
 /// <summary>
 /// An example of encryption/decryption from file to byte array.
 /// </summary>
 /// <param name="key">The secret key to use for the algorithm.</param>
 /// <param name="sourcePath">File path to read.</param>
 /// <returns></returns>
 public static byte[] EncoderRead(byte[] key, string sourcePath)
 {
     using (var rc4 = RC4.Create())
         using (var source = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
             using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 using (var target = new MemoryStream())
                 {
                     crypto.CopyTo(target);
                     return(target.ToArray());
                 }
 }
Exemple #8
0
 /// <summary>
 /// An example of encryption/decryption from one array to another.
 /// </summary>
 /// <param name="key">The secret key to use for the algorithm.</param>
 /// <param name="sourceArray">The byte array to encrypt/decrypt.</param>
 /// <param name="targetArray">The byte array with the resulting data.</param>
 public static void EncoderWrite(byte[] key, byte[] sourceArray, out byte[] targetArray)
 {
     using (var rc4 = RC4.Create())
         using (var source = new MemoryStream(sourceArray))
             using (var target = new MemoryStream())
                 using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 {
                     crypto.CopyTo(target);
                     targetArray = target.ToArray();
                 }
 }
Exemple #9
0
 /// <summary>
 /// An example of file encryption/decryption directly.
 /// </summary>
 /// <param name="key">The secret key to use for the algorithm.</param>
 /// <param name="sourcePath">File path to read/write</param>
 public static void EncoderWrite(byte[] key, string sourcePath)
 {
     using (var rc4 = RC4.Create())
         using (var source = new FileStream(sourcePath, FileMode.Open, FileAccess.ReadWrite))
             using (var target = new MemoryStream())
                 using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 {
                     crypto.CopyTo(target);
                     source.Seek(0, SeekOrigin.Begin);
                     target.Seek(0, SeekOrigin.Begin);
                     target.CopyTo(source);
                 }
 }
Exemple #10
0
 /// <summary>
 /// An example of byte array encryption/decryption directly.
 /// </summary>
 /// <param name="key">The secret key to use for the algorithm.</param>
 /// <param name="sourceArray">The byte array to encrypt/decrypt.</param>
 public static void EncoderWrite(byte[] key, byte[] sourceArray)
 {
     using (var rc4 = RC4.Create())
         using (var source = new MemoryStream(sourceArray))
             using (var target = new MemoryStream())
                 using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                 {
                     crypto.CopyTo(target);
                     source.Seek(0, SeekOrigin.Begin);
                     target.Seek(0, SeekOrigin.Begin);
                     target.CopyTo(source);
                 }
 }
        /// <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)
                RC4 rc4 = RC4.Create();
                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)
                RC4 rc4 = RC4.Create();
                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);
        }
Exemple #12
0
        private bool Decode(byte[] pvk, string password)
        {
            if (BitConverterLE.ToUInt32(pvk, 0) != 2964713758U || BitConverterLE.ToUInt32(pvk, 4) != 0U)
            {
                return(false);
            }
            this.keyType   = BitConverterLE.ToInt32(pvk, 8);
            this.encrypted = BitConverterLE.ToUInt32(pvk, 12) == 1U;
            int int32_1 = BitConverterLE.ToInt32(pvk, 16);
            int int32_2 = BitConverterLE.ToInt32(pvk, 20);

            byte[] numArray = new byte[int32_2];
            Buffer.BlockCopy((Array)pvk, 24 + int32_1, (Array)numArray, 0, int32_2);
            if (int32_1 > 0)
            {
                if (password == null)
                {
                    return(false);
                }
                byte[] salt = new byte[int32_1];
                Buffer.BlockCopy((Array)pvk, 24, (Array)salt, 0, int32_1);
                byte[] rgbKey = this.DeriveKey(salt, password);
                RC4.Create().CreateDecryptor(rgbKey, (byte[])null).TransformBlock(numArray, 8, numArray.Length - 8, numArray, 8);
                try
                {
                    this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                    this.weak = false;
                }
                catch (CryptographicException)
                {
                    this.weak = true;
                    Buffer.BlockCopy((Array)pvk, 24 + int32_1, (Array)numArray, 0, int32_2);
                    Array.Clear((Array)rgbKey, 5, 11);
                    RC4.Create().CreateDecryptor(rgbKey, (byte[])null).TransformBlock(numArray, 8, numArray.Length - 8, numArray, 8);
                    this.rsa = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                }
                Array.Clear((Array)rgbKey, 0, rgbKey.Length);
            }
            else
            {
                this.weak = true;
                this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                Array.Clear((Array)numArray, 0, numArray.Length);
            }
            Array.Clear((Array)pvk, 0, pvk.Length);
            return(this.rsa != null);
        }
Exemple #13
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);
    }
Exemple #14
0
        public void Save(string filename, string password)
        {
            if (filename == null)
            {
                throw new ArgumentNullException(nameof(filename));
            }
            byte[]     numArray1  = (byte[])null;
            FileStream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write);

            try
            {
                byte[] buffer = new byte[4];
                byte[] bytes1 = BitConverterLE.GetBytes(2964713758U);
                fileStream.Write(bytes1, 0, 4);
                fileStream.Write(buffer, 0, 4);
                byte[] bytes2 = BitConverterLE.GetBytes(this.keyType);
                fileStream.Write(bytes2, 0, 4);
                this.encrypted = password != null;
                numArray1      = CryptoConvert.ToCapiPrivateKeyBlob(this.rsa);
                if (this.encrypted)
                {
                    byte[] bytes3 = BitConverterLE.GetBytes(1);
                    fileStream.Write(bytes3, 0, 4);
                    byte[] bytes4 = BitConverterLE.GetBytes(16);
                    fileStream.Write(bytes4, 0, 4);
                    byte[] bytes5 = BitConverterLE.GetBytes(numArray1.Length);
                    fileStream.Write(bytes5, 0, 4);
                    byte[] numArray2 = new byte[16];
                    RC4    rc4       = RC4.Create();
                    byte[] rgbKey    = (byte[])null;
                    try
                    {
                        RandomNumberGenerator.Create().GetBytes(numArray2);
                        fileStream.Write(numArray2, 0, numArray2.Length);
                        rgbKey = this.DeriveKey(numArray2, password);
                        if (this.Weak)
                        {
                            Array.Clear((Array)rgbKey, 5, 11);
                        }
                        rc4.CreateEncryptor(rgbKey, (byte[])null).TransformBlock(numArray1, 8, numArray1.Length - 8, numArray1, 8);
                    }
                    finally
                    {
                        Array.Clear((Array)numArray2, 0, numArray2.Length);
                        Array.Clear((Array)rgbKey, 0, rgbKey.Length);
                        rc4.Clear();
                    }
                }
                else
                {
                    fileStream.Write(buffer, 0, 4);
                    fileStream.Write(buffer, 0, 4);
                    byte[] bytes3 = BitConverterLE.GetBytes(numArray1.Length);
                    fileStream.Write(bytes3, 0, 4);
                }
                fileStream.Write(numArray1, 0, numArray1.Length);
            }
            finally
            {
                Array.Clear((Array)numArray1, 0, numArray1.Length);
                fileStream.Close();
            }
        }
Exemple #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NtlmAuthenticateMessageGenerator"/> class,
        /// which generates an NTLM authentication Authenticate (or Type 3) message.
        /// </summary>
        /// <param name="random">A <see cref="Random"/> object used to generate pseudorandom numbers for generating random keys.</param>
        /// <param name="currentTime"></param>
        /// <param name="domain">The domain against which to authenticate.</param>
        /// <param name="host">The host against which to authenticate.</param>
        /// <param name="user">The user name to use in authenticating.</param>
        /// <param name="password">The password to use in authenticating.</param>
        /// <param name="nonce">The random byte array sent by the server as part of the challenge message.</param>
        /// <param name="negotiatedOptionFlags">The <see cref="NtlmNegotiateFlags"/> sent by the server as part of the challenge message.</param>
        /// <param name="target">The target sent by the server as part of the challenge message.</param>
        /// <param name="targetInformation">The target information structure as an array of bytes sent by the server as part of the challenge message.</param>
        /// <param name="peerServerCertificate">An <see cref="X509Certificate"/> used to cryptographically sign communication between the server and client.</param>
        /// <param name="type1Message">A byte array containing the Negotiate (or Type 1) message used in the handshake.</param>
        /// <param name="type2Message">A byte array containing the Challenge (or Type 2) message used in the handshake.</param>
        public NtlmAuthenticateMessageGenerator(Random random, DateTime currentTime, string domain, string host, string user, string password, byte[] nonce, NtlmNegotiateFlags negotiatedOptionFlags, string target, byte[] targetInformation, X509Certificate peerServerCertificate, byte[] type1Message, byte[] type2Message)
        {
            if (random == null)
            {
                throw new NtlmAuthorizationGenerationException("Random generator not available");
            }

            // Save the flags
            this.negotiatedOptionFlags = negotiatedOptionFlags;
            this.type1Message          = type1Message;
            this.type2Message          = type2Message;

            // Strip off domain name from the host!
            string unqualifiedHost = ConvertHost(host);

            // Use only the base domain name!
            string unqualifiedDomain = ConvertDomain(domain);

            byte[] responseTargetInformation = targetInformation;
            if (peerServerCertificate != null)
            {
                responseTargetInformation      = AddGssMessageIntegrityCodeAttributeValuesToTargetInfo(targetInformation, peerServerCertificate);
                isMessageIntegrityCodeRequired = true;
            }
            else
            {
                isMessageIntegrityCodeRequired = false;
            }

            // Create a cipher generator class.
            // N.B., Use original domain value (before modification).
            CipherGen gen = new CipherGen(random, currentTime, unqualifiedDomain, user, password, nonce, target, responseTargetInformation);

            // Use the new code to calculate the responses, including v2 if that
            // seems warranted.
            byte[] userSessionKey;
            try
            {
                // This conditional may not work on Windows Server 2008 R2 and above,
                // where it has not yet been tested
                if (((negotiatedOptionFlags & NtlmNegotiateFlags.RequestTargetInfo) != 0) && targetInformation != null && target != null)
                {
                    // NTLMv2
                    ntlmResponse = gen.GetNtlmV2Response();
                    lmResponse   = gen.GetLmV2Response();
                    if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestLanManagerKey) != 0)
                    {
                        userSessionKey = gen.GetLanManagerSessionKey();
                    }
                    else
                    {
                        userSessionKey = gen.GetNtlmV2UserSessionKey();
                    }
                }
                else
                {
                    // NTLMv1
                    if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestNtlmV2Session) != 0)
                    {
                        // NTLM2 session stuff is requested
                        ntlmResponse = gen.GetNtlm2SessionResponse();
                        lmResponse   = gen.GetLm2SessionResponse();
                        if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestLanManagerKey) != 0)
                        {
                            userSessionKey = gen.GetLanManagerSessionKey();
                        }
                        else
                        {
                            userSessionKey = gen.GetNtlm2SessionResponseUserSessionKey();
                        }
                    }
                    else
                    {
                        ntlmResponse = gen.GetNtlmResponse();
                        lmResponse   = gen.GetLmResponse();
                        if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestLanManagerKey) != 0)
                        {
                            userSessionKey = gen.GetLanManagerSessionKey();
                        }
                        else
                        {
                            userSessionKey = gen.GetNtlmUserSessionKey();
                        }
                    }
                }
            }
            catch (NtlmAuthorizationGenerationException)
            {
                // This likely means we couldn't find the MD4 hash algorithm -
                // fail back to just using LM
                ntlmResponse = new byte[0];
                lmResponse   = gen.GetLmResponse();
                if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestLanManagerKey) != 0)
                {
                    userSessionKey = gen.GetLanManagerSessionKey();
                }
                else
                {
                    userSessionKey = gen.GetLmUserSessionKey();
                }
            }

            if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestSign) != 0)
            {
                if ((negotiatedOptionFlags & NtlmNegotiateFlags.RequestKeyExchange) != 0)
                {
                    exportedSessionKey = gen.GetSecondaryKey();
                    using (var rc4 = RC4.Create())
                    {
                        rc4.Key    = exportedSessionKey;
                        sessionKey = rc4.CreateEncryptor().TransformFinalBlock(userSessionKey, 0, userSessionKey.Length);
                    }
                }
                else
                {
                    sessionKey         = userSessionKey;
                    exportedSessionKey = sessionKey;
                }
            }
            else
            {
                if (isMessageIntegrityCodeRequired)
                {
                    throw new NtlmAuthorizationGenerationException("Cannot sign/seal: no exported session key");
                }

                sessionKey         = null;
                exportedSessionKey = null;
            }

            Encoding charset = GetCharset(negotiatedOptionFlags);

            if (unqualifiedHost != null)
            {
                hostBytes = charset.GetBytes(unqualifiedHost);
            }

            if (unqualifiedDomain != null)
            {
                domainBytes = charset.GetBytes(unqualifiedDomain.ToUpperInvariant());
            }

            userBytes = charset.GetBytes(user);
        }
Exemple #16
0
        public void Save(string filename, string password)
        {
            if (filename == null)
            {
                throw new ArgumentNullException("filename");
            }
            byte[]     array      = null;
            FileStream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write);

            try
            {
                byte[] array2 = new byte[4];
                byte[] bytes  = BitConverterLE.GetBytes(2964713758u);
                fileStream.Write(bytes, 0, 4);
                fileStream.Write(array2, 0, 4);
                bytes = BitConverterLE.GetBytes(this.keyType);
                fileStream.Write(bytes, 0, 4);
                this.encrypted = (password != null);
                array          = CryptoConvert.ToCapiPrivateKeyBlob(this.rsa);
                if (this.encrypted)
                {
                    bytes = BitConverterLE.GetBytes(1);
                    fileStream.Write(bytes, 0, 4);
                    bytes = BitConverterLE.GetBytes(16);
                    fileStream.Write(bytes, 0, 4);
                    bytes = BitConverterLE.GetBytes(array.Length);
                    fileStream.Write(bytes, 0, 4);
                    byte[] array3 = new byte[16];
                    RC4    rc     = RC4.Create();
                    byte[] array4 = null;
                    try
                    {
                        RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
                        randomNumberGenerator.GetBytes(array3);
                        fileStream.Write(array3, 0, array3.Length);
                        array4 = this.DeriveKey(array3, password);
                        if (this.Weak)
                        {
                            Array.Clear(array4, 5, 11);
                        }
                        ICryptoTransform cryptoTransform = rc.CreateEncryptor(array4, null);
                        cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                    }
                    finally
                    {
                        Array.Clear(array3, 0, array3.Length);
                        Array.Clear(array4, 0, array4.Length);
                        rc.Clear();
                    }
                }
                else
                {
                    fileStream.Write(array2, 0, 4);
                    fileStream.Write(array2, 0, 4);
                    bytes = BitConverterLE.GetBytes(array.Length);
                    fileStream.Write(bytes, 0, 4);
                }
                fileStream.Write(array, 0, array.Length);
            }
            finally
            {
                Array.Clear(array, 0, array.Length);
                fileStream.Close();
            }
        }
Exemple #17
0
        static void Main(string[] args)
        {
            // Put in the "Debug" folder of this Project "source.txt" file for debugging...
            byte[] key   = Encoding.ASCII.GetBytes("SecREt01pAssW0rd");
            string path1 = @"source.txt";
            string path2 = @"encoded.txt";
            string path3 = @"decoded.txt";

            // Example without reuse Encryptor (ICryptoTransform).
            // Allows you to get the same results every time you encrypt the same file.
            // To decrypt the result, you need to apply the algorithm again.
            byte[][] encoded1;
            using (RC4 rc4 = RC4.Create())
            {
                encoded1 = new byte[3][];
                for (int i = 0; i < 3; i++)
                {
                    using (var source = new FileStream(path1, FileMode.Open, FileAccess.Read))
                        using (var crypto = new CryptoStream(source, rc4.CreateEncryptor(key, null), CryptoStreamMode.Read))
                            using (var target = new MemoryStream())
                            {
                                crypto.CopyTo(target);
                                encoded1[i] = target.ToArray();
                            }
                }
            }

            // Example with reuse Encryptor (ICryptoTransform).
            // Allows you to get different results when encrypting even the same file.
            // To decrypt each file, you need to re-apply the algorithm in the same order.
            byte[][] encoded2;
            using (RC4 rc4 = RC4.Create())
            {
                ICryptoTransform encryptor = rc4.CreateEncryptor(key, null);
                encoded2 = new byte[3][];
                for (int i = 0; i < 3; i++)
                {
                    using (var source = new FileStream(path1, FileMode.Open, FileAccess.Read))
                        using (var crypto = new CryptoStream(source, encryptor, CryptoStreamMode.Read))
                            using (var target = new MemoryStream())
                            {
                                crypto.CopyTo(target);
                                encoded2[i] = target.ToArray();
                            }
                }
            }

            // All sorts of templates for encryption/decryption.

            // Encryption path1 to path2
            EncoderWrite(key, path1, path2);
            Console.WriteLine($"The contents of file {path1} is encrypted in file {path2}.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Decryption path2 to path3
            EncoderWrite(key, path2, path3);
            Console.WriteLine($"The contents of file {path2} is decrypted in file {path3}.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Encryption path3
            EncoderWrite(key, path3);
            Console.WriteLine($"The contents of file {path3} is encrypted.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Decryption path3
            EncoderWrite(key, path3);
            Console.WriteLine($"The contents of file {path3} is decrypted.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Encryption path1 to buffer
            byte[] buffer = EncoderRead(key, path1);
            Console.WriteLine($"The contents of file {path1} is encrypted in the buffer.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Decryption buffer
            EncoderWrite(key, buffer);
            Console.WriteLine($"The contents of buffer is decrypted.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Encryption buffer to buffer2
            byte[] buffer2 = new byte[123];
            EncoderWrite(key, buffer, out buffer2);
            Console.WriteLine($"The contents of buffer is encrypted in the buffer2.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
            // Decryption buffer2 to path3
            EncoderWrite(key, buffer2, path3);
            Console.WriteLine($"The contents of buffer2 is decrypted in file {path3}.");
            Console.WriteLine("Press any key...");
            Console.ReadLine();
        }
        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);
        }
        public void Save(string filename, string password)
        {
            if (filename == null)
            {
                throw new ArgumentNullException("filename");
            }

            byte[]     blob = null;
            FileStream fs   = File.Open(filename, FileMode.Create, FileAccess.Write);

            try
            {
                // header
                byte[] empty = new byte [4];
                byte[] data  = BitConverterLE.GetBytes(magic);
                fs.Write(data, 0, 4);   // magic
                fs.Write(empty, 0, 4);  // reserved
                data = BitConverterLE.GetBytes(keyType);
                fs.Write(data, 0, 4);   // key type

                encrypted = (password != null);
                blob      = CryptoConvert.ToCapiPrivateKeyBlob(rsa);
                if (encrypted)
                {
                    data = BitConverterLE.GetBytes(1);
                    fs.Write(data, 0, 4); // encrypted
                    data = BitConverterLE.GetBytes(16);
                    fs.Write(data, 0, 4); // saltlen
                    data = BitConverterLE.GetBytes(blob.Length);
                    fs.Write(data, 0, 4); // keylen

                    byte[] salt = new byte [16];
                    RC4    rc4  = RC4.Create();
                    byte[] key  = null;
                    try
                    {
                        // generate new salt (16 bytes)
                        RandomNumberGenerator rng = RandomNumberGenerator.Create();
                        rng.GetBytes(salt);
                        fs.Write(salt, 0, salt.Length);
                        key = DeriveKey(salt, password);
                        if (Weak)
                        {
                            Array.Clear(key, 5, 11);
                        }
                        ICryptoTransform enc = rc4.CreateEncryptor(key, null);
                        // we don't encrypt the header part of the BLOB
                        enc.TransformBlock(blob, 8, blob.Length - 8, blob, 8);
                    }
                    finally
                    {
                        Array.Clear(salt, 0, salt.Length);
                        Array.Clear(key, 0, key.Length);
                        rc4.Clear();
                    }
                }
                else
                {
                    fs.Write(empty, 0, 4); // encrypted
                    fs.Write(empty, 0, 4); // saltlen
                    data = BitConverterLE.GetBytes(blob.Length);
                    fs.Write(data, 0, 4);  // keylen
                }

                fs.Write(blob, 0, blob.Length);
            }
            finally
            {
                // BLOB may include an uncrypted keypair
                Array.Clear(blob, 0, blob.Length);
                fs.Close();
            }
        }
        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
        }