public String Encrypt(List <byte> payload) { if (_key.Count() == 0) { throw new Exception("Key hasn't been derived yet, encryption isn't available"); } string encPayload = null; byte[] key = null; try { var result = new List <byte>(); using (var aes = new System.Security.Cryptography.AesManaged()) { aes.Mode = System.Security.Cryptography.CipherMode.CBC; aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7; aes.GenerateIV(); result.AddRange(aes.IV); key = _key.ToArray(); System.Security.Cryptography.ProtectedMemory.Unprotect(key, System.Security.Cryptography.MemoryProtectionScope.SameProcess); aes.Key = key; var enc = aes.CreateEncryptor(); result.AddRange(enc.TransformFinalBlock(payload.ToArray(), 0, payload.Count)); encPayload = System.Convert.ToBase64String(result.ToArray()); result.Clear(); } } catch (Exception ex) { throw new Exception("Encryption failed " + ex.Message); } finally { if (key != null) { Array.Clear(key, 0, key.Length); } } return(encPayload); }
public bool Connect(string host, int port, string module, bool requirewrite = false) { if (port == -1) port = VersionrDefaultPort; IEnumerator<SharedNetwork.Protocol> protocols = SharedNetwork.AllowedProtocols.Cast<SharedNetwork.Protocol>().GetEnumerator(); Retry: if (!protocols.MoveNext()) { Printer.PrintMessage("#e#No valid protocols available.##"); return false; } Host = host; Port = port; Module = module; Connected = false; try { Connection = new System.Net.Sockets.TcpClient(); var connectionTask = Connection.ConnectAsync(Host, Port); if (!connectionTask.Wait(5000)) { throw new Exception(string.Format("Couldn't connect to target: {0}", this.VersionrURL)); } } catch (Exception e) { Printer.PrintError(e.Message); return false; } if (Connection.Connected) { try { Printer.PrintDiagnostics("Connected to server at {0}:{1}", host, port); Handshake hs = Handshake.Create(protocols.Current); hs.RequestedModule = Module; Printer.PrintDiagnostics("Sending handshake..."); Connection.NoDelay = true; ProtoBuf.Serializer.SerializeWithLengthPrefix<Handshake>(Connection.GetStream(), hs, ProtoBuf.PrefixStyle.Fixed32); var startTransaction = ProtoBuf.Serializer.DeserializeWithLengthPrefix<Network.StartTransaction>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32); if (startTransaction == null || !startTransaction.Accepted) { Printer.PrintError("#b#Server rejected connection.##"); if (startTransaction != null && hs.VersionrProtocol != startTransaction.ServerHandshake.VersionrProtocol) Printer.PrintError("## Protocol mismatch - local: {0}, remote: {1}", hs.VersionrProtocol, startTransaction.ServerHandshake.VersionrProtocol); else { if (startTransaction == null) Printer.PrintError("## Connection terminated unexpectedly."); else Printer.PrintError("## Rejected request."); return false; } Printer.PrintError("#b#Attempting to retry with a lower protocol.##"); goto Retry; } Printer.PrintDiagnostics("Server domain: {0}", startTransaction.Domain); if (Workspace != null && !string.IsNullOrEmpty(startTransaction.Domain) && startTransaction.Domain != Workspace.Domain.ToString()) { Printer.PrintError("Server domain doesn't match client domain. Disconnecting."); return false; } RemoteDomain = startTransaction.Domain; if (SharedNetwork.SupportsAuthentication(startTransaction.ServerHandshake.CheckProtocol().Value)) { var command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32); if (command.Type == NetCommandType.Authenticate) { bool runauth = true; var challenge = ProtoBuf.Serializer.DeserializeWithLengthPrefix<AuthenticationChallenge>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32); if ((!requirewrite && (command.Identifier & 1) != 0) || (requirewrite && (command.Identifier & 2) != 0)) // server supports unauthenticated access { AuthenticationResponse response = new AuthenticationResponse() { IdentifierToken = string.Empty, Mode = AuthenticationMode.Guest }; ProtoBuf.Serializer.SerializeWithLengthPrefix(Connection.GetStream(), response, ProtoBuf.PrefixStyle.Fixed32); command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32); if (command.Type == NetCommandType.Acknowledge) runauth = false; } if (runauth) { bool q = Printer.Quiet; Printer.Quiet = false; Printer.PrintMessage("Server at #b#{0}## requires authentication.", VersionrURL); while (true) { if (challenge.AvailableModes.Contains(AuthenticationMode.Simple)) { System.Console.CursorVisible = true; Printer.PrintMessageSingleLine("#b#Username:## "); string user = System.Console.ReadLine(); Printer.PrintMessageSingleLine("#b#Password:## "); string pass = GetPassword(); System.Console.CursorVisible = false; user = user.Trim(new char[] { '\r', '\n', ' ' }); AuthenticationResponse response = new AuthenticationResponse() { IdentifierToken = user, Mode = AuthenticationMode.Simple, Payload = System.Text.ASCIIEncoding.ASCII.GetBytes(BCrypt.Net.BCrypt.HashPassword(pass, challenge.Salt)) }; Printer.PrintMessage("\n"); ProtoBuf.Serializer.SerializeWithLengthPrefix(Connection.GetStream(), response, ProtoBuf.PrefixStyle.Fixed32); command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32); if (command.Type == NetCommandType.AuthRetry) Printer.PrintError("#e#Authentication failed.## Retry."); if (command.Type == NetCommandType.AuthFail) { Printer.PrintError("#e#Authentication failed.##"); return false; } if (command.Type == NetCommandType.Acknowledge) break; } else { Printer.PrintError("Unsupported authentication requirements!"); return false; } } Printer.Quiet = q; } } } if (startTransaction.Encrypted) { var key = startTransaction.RSAKey; Printer.PrintDiagnostics("Server RSA Key: {0}", key.Fingerprint()); var publicKey = new System.Security.Cryptography.RSACryptoServiceProvider(); publicKey.ImportParameters(key); Printer.PrintDiagnostics("Generating secret key for data channel..."); System.Security.Cryptography.RSAOAEPKeyExchangeFormatter exch = new System.Security.Cryptography.RSAOAEPKeyExchangeFormatter(publicKey); System.Security.Cryptography.AesManaged aesProvider = new System.Security.Cryptography.AesManaged(); aesProvider.KeySize = 256; aesProvider.GenerateIV(); aesProvider.GenerateKey(); AESProvider = aesProvider; AESKey = aesProvider.Key; AESIV = aesProvider.IV; Printer.PrintDiagnostics("Key: {0}", System.Convert.ToBase64String(aesProvider.Key)); var keyExchangeObject = new Network.StartClientTransaction() { Key = exch.CreateKeyExchange(aesProvider.Key), IV = exch.CreateKeyExchange(aesProvider.IV) }; ProtoBuf.Serializer.SerializeWithLengthPrefix<StartClientTransaction>(Connection.GetStream(), keyExchangeObject, ProtoBuf.PrefixStyle.Fixed32); Connection.GetStream().Flush(); Connected = true; SharedNetwork.SharedNetworkInfo sharedInfo = new SharedNetwork.SharedNetworkInfo() { DecryptorFunction = () => { return Decryptor; }, EncryptorFunction = () => { return Encryptor; }, Stream = Connection.GetStream(), Workspace = Workspace, Client = true, CommunicationProtocol = protocols.Current }; SharedInfo = sharedInfo; } else { Printer.PrintDiagnostics("Using cleartext communication"); var keyExchangeObject = new Network.StartClientTransaction(); ProtoBuf.Serializer.SerializeWithLengthPrefix<StartClientTransaction>(Connection.GetStream(), keyExchangeObject, ProtoBuf.PrefixStyle.Fixed32); Connection.GetStream().Flush(); Connected = true; SharedNetwork.SharedNetworkInfo sharedInfo = new SharedNetwork.SharedNetworkInfo() { DecryptorFunction = null, EncryptorFunction = null, Stream = Connection.GetStream(), Workspace = Workspace, Client = true, CommunicationProtocol = protocols.Current }; SharedInfo = sharedInfo; } return true; } catch (Exception e) { Printer.PrintError("Error encountered: {0}", e); return false; } } else return false; }
public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] cryptKey, byte[] authKey, byte[] nonSecretPayload = null) { //User Error Checks if (cryptKey == null || cryptKey.Length != KeyBitSize / 8) { throw new System.ArgumentException(string.Format("Key needs to be {0} bit!", KeyBitSize), "cryptKey"); } if (authKey == null || authKey.Length != KeyBitSize / 8) { throw new System.ArgumentException(string.Format("Key needs to be {0} bit!", KeyBitSize), "authKey"); } if (secretMessage == null || secretMessage.Length < 1) { throw new System.ArgumentException("Secret Message Required!", "secretMessage"); } //non-secret payload optional nonSecretPayload = nonSecretPayload ?? new byte[] { }; byte[] cipherText; byte[] iv; using (System.Security.Cryptography.AesManaged aes = new System.Security.Cryptography.AesManaged { KeySize = KeyBitSize, BlockSize = BlockBitSize, Mode = System.Security.Cryptography.CipherMode.CBC, Padding = System.Security.Cryptography.PaddingMode.PKCS7 }) { //Use random IV aes.GenerateIV(); iv = aes.IV; using (System.Security.Cryptography.ICryptoTransform encrypter = aes.CreateEncryptor(cryptKey, iv)) using (System.IO.MemoryStream cipherStream = new System.IO.MemoryStream()) { using (System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(cipherStream, encrypter, System.Security.Cryptography.CryptoStreamMode.Write)) using (System.IO.BinaryWriter binaryWriter = new System.IO.BinaryWriter(cryptoStream)) { //Encrypt Data binaryWriter.Write(secretMessage); } cipherText = cipherStream.ToArray(); } } //Assemble encrypted message and add authentication using (System.Security.Cryptography.HMACSHA256 hmac = new System.Security.Cryptography.HMACSHA256(authKey)) using (System.IO.MemoryStream encryptedStream = new System.IO.MemoryStream()) { using (System.IO.BinaryWriter binaryWriter = new System.IO.BinaryWriter(encryptedStream)) { //Prepend non-secret payload if any binaryWriter.Write(nonSecretPayload); //Prepend IV binaryWriter.Write(iv); //Write Ciphertext binaryWriter.Write(cipherText); binaryWriter.Flush(); //Authenticate all data byte[] tag = hmac.ComputeHash(encryptedStream.ToArray()); //Postpend tag binaryWriter.Write(tag); } return(encryptedStream.ToArray()); } }