/// <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 TestDecryption() { int tests = 0; RC4 rc4 = GetRC4Instance(); ICryptoTransform enc = null; byte[] ret = null; // test TransformBlock for (int i = 0; i < keys.Length; i++) { try { enc = rc4.CreateDecryptor(keys[i], null); } catch { AddError("RC4-TD1"); } try { ret = new byte[outputs[i].Length]; enc.TransformBlock(outputs[i], 0, outputs[i].Length, ret, 0); } catch { AddError("RC4-TD2"); } if (!ArrayEquals(ret, inputs[i])) { AddError("RC4-TD3"); } if (enc != null) { enc.Dispose(); } tests += 3; } // test TransformFinalBlock for (int i = 0; i < keys.Length; i++) { try { enc = rc4.CreateDecryptor(keys[i], null); } catch { AddError("RC4-TD4"); } try { ret = enc.TransformFinalBlock(outputs[i], 0, outputs[i].Length); } catch { AddError("RC4-TD5"); } if (!ArrayEquals(ret, inputs[i])) { AddError("RC4-TD6"); } if (enc != null) { enc.Dispose(); } tests += 3; } return(tests); }
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)); } }
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); }
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]); } }
// =========================加密相关=================================== // 加密通讯 public void Encrypt(Int32 send_seed, Int32 receive_seed) { Byte[] _send = BitConverter.GetBytes(send_seed); if (BitConverter.IsLittleEndian) { Array.Reverse(_send); } Byte[] _recv = BitConverter.GetBytes(receive_seed); if (BitConverter.IsLittleEndian) { Array.Reverse(_recv); } string key1; string key2; Byte[] _key1 = dhEnc.DecryptKeyExchange(_send); BigInteger bi1 = new BigInteger(_key1); key1 = Config.SALT + bi1.ToString(); Byte[] _key2 = dhDec.DecryptKeyExchange(_recv); BigInteger bi2 = new BigInteger(_key2); key2 = Config.SALT + bi2.ToString(); RC4 rc4enc = RC4.Create(); RC4 rc4dec = RC4.Create(); Byte[] seed1 = Encoding.ASCII.GetBytes(key1); Byte[] seed2 = Encoding.ASCII.GetBytes(key2); // en/decryptor不为null时自动启动加密 // Get an encryptor. encryptor = rc4enc.CreateEncryptor(seed1, null); // Get a decryptor. decryptor = rc4dec.CreateDecryptor(seed2, null); }
private bool Decode(byte[] pvk, string password) { // DWORD magic if (BitConverterLE.ToUInt32(pvk, 0) != magic) { return(false); } // DWORD reserved if (BitConverterLE.ToUInt32(pvk, 4) != 0x0) { return(false); } // DWORD keytype keyType = BitConverterLE.ToInt32(pvk, 8); // DWORD encrypted encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1); // DWORD saltlen int saltlen = BitConverterLE.ToInt32(pvk, 16); // DWORD keylen int keylen = BitConverterLE.ToInt32(pvk, 20); byte[] keypair = new byte [keylen]; Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen); // read salt (if present) if (saltlen > 0) { if (password == null) { return(false); } byte[] salt = new byte [saltlen]; Buffer.BlockCopy(pvk, 24, salt, 0, saltlen); // first try with full (128) bits byte[] key = DeriveKey(salt, password); // decrypt in place and try this RC4 rc4 = RC4.Create(); ICryptoTransform dec = rc4.CreateDecryptor(key, null); dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8); try { rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair); weak = false; } catch (CryptographicException) { weak = true; // second chance using weak crypto Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen); // truncate the key to 40 bits Array.Clear(key, 5, 11); // decrypt RC4 rc4b = RC4.Create(); dec = rc4b.CreateDecryptor(key, null); dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8); rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair); } Array.Clear(key, 0, key.Length); } else { weak = true; // read unencrypted keypair rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair); Array.Clear(keypair, 0, keypair.Length); } // zeroize pvk (which could contain the unencrypted private key) Array.Clear(pvk, 0, pvk.Length); return(rsa != null); }
internal void GenerateSessionKey(byte[] clientRandom, byte[] serverRandom) { if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { byte[] mackey = null; byte[] clientEncKey = null; byte[] clientDecKey = null; GenerateNonFIPSSessionKey(clientRandom, serverRandom, out mackey, out clientEncKey, out clientDecKey); if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT) { // MACKey40 = 0xD1269E + Last40Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_40BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(40, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(40, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(40, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT) { // MACKey56 = 0xD1 + Last56Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_56BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(56, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(56, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(56, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else // encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT { macKey = mackey; currentClientEncryptKey = clientEncKey; currentServerDecryptKey = clientEncKey; currentClientDecryptKey = clientDecKey; currentServerEncryptKey = clientDecKey; } initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerEncryptKey = currentServerEncryptKey; initialServerDecryptKey = currentServerDecryptKey; RC4 rc4Enc = RC4.Create(); rc4Encrypt = rc4Enc.CreateEncryptor(currentClientEncryptKey, null); rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null); RC4 rc4Dec = RC4.Create(); rc4Decrypt = rc4Dec.CreateDecryptor(currentClientDecryptKey, null); rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS) { GenerateFIPSSessionKey(clientRandom, serverRandom, out macKey, out currentClientEncryptKey, out currentClientDecryptKey, out currentServerEncryptKey, out currentServerDecryptKey); initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerDecryptKey = currentServerDecryptKey; initialServerEncryptKey = currentServerEncryptKey; // suppress "CA5353:TripleDESCannotBeUsed" message, since TripleDES is used according protocol definition in MS-RDPBCGR desEncrypt = new TripleDESCryptoServiceProvider(); desEncrypt.IV = ConstValue.TRPLE_DES_IV; desEncrypt.Key = currentClientEncryptKey; desEncrypt.Mode = CipherMode.CBC; desDecrypt = new TripleDESCryptoServiceProvider(); desDecrypt.IV = ConstValue.TRPLE_DES_IV; desDecrypt.Key = currentClientDecryptKey; desDecrypt.Mode = CipherMode.CBC; desEncryptServer = new TripleDESCryptoServiceProvider(); desEncryptServer.IV = ConstValue.TRPLE_DES_IV; desEncryptServer.Key = currentServerEncryptKey; desEncryptServer.Mode = CipherMode.CBC; desDecryptServer = new TripleDESCryptoServiceProvider(); desDecryptServer.IV = ConstValue.TRPLE_DES_IV; desDecryptServer.Key = currentServerDecryptKey; desDecryptServer.Mode = CipherMode.CBC; } else // the encryption method is ENCRYPTION_METHOD_NONE or error { macKey = null; initialClientEncryptKey = null; initialClientDecryptKey = null; currentClientEncryptKey = null; currentClientDecryptKey = null; initialServerEncryptKey = null; initialServerDecryptKey = null; currentServerEncryptKey = null; currentServerDecryptKey = null; rc4Encrypt = null; rc4Decrypt = null; rc4EncryptServer = null; rc4DecryptServer = null; desEncrypt = null; desDecrypt = null; desEncryptServer = null; desDecryptServer = null; } // the cumulative encryption/decryption count // indicating how many encryptions/decryptions have been carried out. encryptionCount = 0; // the first encryption start with 0 decryptionCount = -1; // after the first decryption, decryptionCount++ up to 0 }