/// <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); }
/// <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); } }
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); }
/// <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()); } }
/// <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()); } }
/// <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(); } }
/// <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); } }
/// <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); }
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); }
// =========================加密相关=================================== // 加密通讯 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(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(); } }
/// <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); }
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(); }
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 }