/// <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 }
protected int TestEncryption() { 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.CreateEncryptor(keys[i], null); } catch { AddError("RC4-TE1"); } try { ret = new byte[inputs[i].Length]; enc.TransformBlock(inputs[i], 0, inputs[i].Length, ret, 0); } catch { AddError("RC4-TE2"); } if (!ArrayEquals(ret, outputs[i])) { AddError("RC4-TE3"); } if (enc != null) { enc.Dispose(); } tests += 3; } // test TransformFinalBlock for (int i = 0; i < keys.Length; i++) { try { enc = rc4.CreateEncryptor(keys[i], null); } catch { AddError("RC4-TE4"); } try { ret = enc.TransformFinalBlock(inputs[i], 0, inputs[i].Length); } catch { AddError("RC4-TE5"); } if (!ArrayEquals(ret, outputs[i])) { AddError("RC4-TE6"); } if (enc != null) { enc.Dispose(); } tests += 3; } return(tests); }
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)); } }
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); }
/// <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) { RC4 rc4Enc = Microsoft.Protocols.TestTools.StackSdk.Security.Cryptographic.RC4.Create(); ICryptoTransform rc4Encrypt = rc4Enc.CreateEncryptor(licensingEncryptionKey, null); byte[] output = new byte[input.Length]; rc4Encrypt.TransformBlock(input, 0, input.Length, output, 0); return(output); }
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]); } }
/// <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); }
// =========================加密相关=================================== // 加密通讯 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); }
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(); } }
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(); } }
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(); } }
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(); }
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 }