static void Main(string[] args) { // Set colors to green on black, because everyone knows that's what hackers use Console.ForegroundColor = ConsoleColor.Green; Console.BackgroundColor = ConsoleColor.Black; Console.Clear(); // Show banner Console.WriteLine("Developer Secrets Sender - Generation 4 (symmetric encryption with asymmetric key exchange)"); Console.WriteLine("Copyright (c) Michal A. Valasek - Altairis, 2016"); Console.WriteLine(new string('-', Console.WindowWidth - 1)); Console.WriteLine(); // Get your partner's public key Console.WriteLine("Enter your partner's public key:"); var partnerPublicKeyString = Console.ReadLine(); var partnerPublicKey = partnerPublicKeyString.FromBase16().ToPublicKeyFromBlob(); Console.WriteLine(); // Create ephemeral bundle var ephemeralBundle = partnerPublicKey.GetSharedEphemeralDhmSecret(); // Send ephemeral public key to partner var ephemeralPublicKeyString = ephemeralBundle.EphemeralDhmPublicKeyBlob.ToBase16(); Console.WriteLine("This is your ephemeral public key:"); Console.WriteLine(ephemeralPublicKeyString); Console.WriteLine("Send it to your chat partner. The adversary can read the key, but should not be able modify it."); Console.WriteLine(); // Get shared secret (master key) var masterKey = ephemeralBundle.SharedSecret; Console.WriteLine("This is your master key (displayed for demonstration only): "); Console.WriteLine(masterKey.ToBase16()); Console.WriteLine(); // Get queue var q = GetQueue(CONNECTION_STRING, QUEUE_NAME); // Main loop Console.WriteLine("Enter message to send or empty string to quit:"); uint messageNumber = 0; while (true) { // Get message to send Console.Write("> "); var line = Console.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { break; } // Increment counter messageNumber++; // Derive key using NIST SP 800-108 algorithm in counter mode var context = BitConverter.GetBytes(messageNumber); var derivedKey = new byte[32].AsArraySegment(); SP800_108_Ctr.DeriveKey(HMACFactories.HMACSHA256, masterKey, null, context.AsArraySegment(), derivedKey, messageNumber); // Encrypt message var encryptedData = SuiteB.Encrypt(derivedKey.Array, line.ToBytes().AsArraySegment()); var encryptedString = string.Join("|", messageNumber, encryptedData.ToBase16()); // Prepare and send message var msg = new CloudQueueMessage(encryptedString); q.AddMessage(msg); // Display results Console.WriteLine($"< Message #{messageNumber} sent"); } Console.WriteLine("Program terminated successfully"); }
static void Main(string[] args) { // Set colors to green on black, because everyone knows that's what hackers use Console.ForegroundColor = ConsoleColor.Green; Console.BackgroundColor = ConsoleColor.Black; Console.Clear(); // Show banner Console.WriteLine("Developer Secrets Receiver - Generation 3 (symmetric encryption with key derivation)"); Console.WriteLine("Copyright (c) Michal A. Valasek - Altairis, 2016"); Console.WriteLine(new string('-', Console.WindowWidth - 1)); Console.WriteLine(); // Create master symmetric key var rnd = new CryptoRandom(); var masterKey = rnd.NextBytes(32); var masterKeyString = masterKey.ToBase16(); Console.WriteLine("This is your master symmetric key: " + masterKeyString); Console.WriteLine("Send it to your chat partner safely!"); Console.WriteLine(); // Get queue var q = GetQueue(CONNECTION_STRING, QUEUE_NAME); // Main loop Console.WriteLine("Waiting for messages. Press SPACEBAR for pause, ESC for exit."); Console.WriteLine(); uint expectedMessageNumber = 1; while (true) { // Wait to receive message var msg = q.GetMessage(); if (msg == null) { // No more messages if (Console.KeyAvailable) { var keyCode = Console.ReadKey(intercept: true); if (keyCode.Key == ConsoleKey.Escape) { break; } if (keyCode.Key == ConsoleKey.Spacebar) { Console.WriteLine(); Console.WriteLine("Paused, press any key to continue..."); Console.ReadKey(intercept: true); Console.WriteLine("Waiting for messages. Press SPACEBAR for pause, ESC for exit."); Console.WriteLine(); } } Thread.Sleep(250); continue; } // Delete message from queue q.DeleteMessage(msg); // Parse message var messageParts = msg.AsString.Split('|'); uint messageNumber = uint.Parse(messageParts[0]); var cipherData = messageParts[1].FromBase16(); // Validate message number if (messageNumber < expectedMessageNumber) { // Received number is too low - message is repeated or out of order Console.WriteLine($"WARNING! The following message has too low serial number (expected {expectedMessageNumber}, got {messageNumber}."); Console.WriteLine($" Message is repeated or was delivered out of order."); } else if (messageNumber > expectedMessageNumber) { // Received number is too high - some messages are missing or out of order Console.WriteLine($"WARNING! The following message has too high serial number (expected {expectedMessageNumber}, got {messageNumber}."); Console.WriteLine($" Message was delivered out of order or some messages are missing."); expectedMessageNumber = messageNumber + 1; } else { // Received number is correct expectedMessageNumber++; } // Derive key using HKDF algorithm var context = BitConverter.GetBytes(messageNumber); var derivedKey = new byte[32].AsArraySegment(); SP800_108_Ctr.DeriveKey(HMACFactories.HMACSHA256, masterKey, null, context.AsArraySegment(), derivedKey, messageNumber); // Authenticate message var authenticated = SuiteB.Authenticate(derivedKey.Array, cipherData.AsArraySegment()); if (!authenticated) { Console.WriteLine($"< Message #{messageNumber} ({msg.Id}) from {msg.InsertionTime:yyyy-MM-dd HH:mm:ss} was tampered with!"); continue; } // Decrypt message var plainData = SuiteB.Decrypt(derivedKey.Array, cipherData.AsArraySegment()); var plainString = plainData.FromBytes(); // Display message Console.WriteLine($"< Message #{messageNumber} ({msg.Id}) from {msg.InsertionTime:yyyy-MM-dd HH:mm:ss}:"); Console.WriteLine(plainString); } Console.WriteLine("Program terminated successfully."); }
static void Main(string[] args) { // Set colors to green on black, because everyone knows that's what hackers use Console.ForegroundColor = ConsoleColor.Green; Console.BackgroundColor = ConsoleColor.Black; Console.Clear(); // Show banner Console.WriteLine("Developer Secrets Sender - Generation 3 (symmetric encryption with key derivation)"); Console.WriteLine("Copyright (c) Michal A. Valasek - Altairis, 2016"); Console.WriteLine(new string('-', Console.WindowWidth - 1)); Console.WriteLine(); // Get secret key Console.Write("Enter your partner's master symmetric key: "); var masterKeyString = Console.ReadLine(); var masterKey = masterKeyString.FromBase16(); Console.WriteLine(); // Get queue var q = GetQueue(CONNECTION_STRING, QUEUE_NAME); // Main loop Console.WriteLine("Enter message to send or empty string to quit:"); uint messageNumber = 0; while (true) { // Get message to send Console.Write("> "); var line = Console.ReadLine(); if (string.IsNullOrWhiteSpace(line)) { break; } // Increment counter messageNumber++; // Derive key using NIST SP 800-108 algorithm in counter mode var context = BitConverter.GetBytes(messageNumber); var derivedKey = new byte[32].AsArraySegment(); SP800_108_Ctr.DeriveKey( HMACFactories.HMACSHA256, masterKey, null, context.AsArraySegment(), derivedKey, messageNumber); // Encrypt message var encryptedData = SuiteB.Encrypt(derivedKey.Array, line.ToBytes().AsArraySegment()); var encryptedString = string.Join("|", messageNumber, encryptedData.ToBase16()); // Prepare and send message var msg = new CloudQueueMessage(encryptedString); q.AddMessage(msg); // Display results Console.WriteLine($"< Message #{messageNumber} sent"); } Console.WriteLine("Program terminated successfully"); }