I'm writing a chat. I want to encrypt messages using the Diffie Hellman algorithm . Suppose the algorithm is implemented and now we have the coveted key. What are the algorithms to encrypt an array of bytes (message) with this key?

Help please understand:

using System; using System.IO; using System.Security.Cryptography; using System.Text; class Alice { public static byte[] alicePublicKey; public static void Main(string[] args) { using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng()) { alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; alice.HashAlgorithm = CngAlgorithm.Sha256; alicePublicKey = alice.PublicKey.ToByteArray(); Bob bob = new Bob(); CngKey k = CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob); byte[] aliceKey = alice.DeriveKeyMaterial(k); byte[] encryptedMessage = null; byte[] iv = null; Send(aliceKey, "Secret message", out encryptedMessage, out iv); bob.Receive(encryptedMessage, iv); } } private static void Send(byte[] key, string secretMessage, out byte[] encryptedMessage, out byte[] iv) { using (Aes aes = new AesCryptoServiceProvider()) { aes.Key = key; iv = aes.IV; // Encrypt the message using (MemoryStream ciphertext = new MemoryStream()) using (CryptoStream cs = new CryptoStream(ciphertext, aes.CreateEncryptor(), CryptoStreamMode.Write)) { byte[] plaintextMessage = Encoding.UTF8.GetBytes(secretMessage); cs.Write(plaintextMessage, 0, plaintextMessage.Length); cs.Close(); encryptedMessage = ciphertext.ToArray(); } } } } public class Bob { public byte[] bobPublicKey; private byte[] bobKey; public Bob() { using (ECDiffieHellmanCng bob = new ECDiffieHellmanCng()) { bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; bob.HashAlgorithm = CngAlgorithm.Sha256; bobPublicKey = bob.PublicKey.ToByteArray(); bobKey = bob.DeriveKeyMaterial(CngKey.Import(Alice.alicePublicKey, CngKeyBlobFormat.EccPublicBlob)); } } public void Receive(byte[] encryptedMessage, byte[] iv) { using (Aes aes = new AesCryptoServiceProvider()) { aes.Key = bobKey; aes.IV = iv; // Decrypt the message using (MemoryStream plaintext = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(plaintext, aes.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(encryptedMessage, 0, encryptedMessage.Length); cs.Close(); string message = Encoding.UTF8.GetString(plaintext.ToArray()); Console.WriteLine(message); } } } } } 

Why do I need an iv array?

  • 2
    > algorithm implemented. What is it like? they did it themselves or took it here msdn.microsoft.com/ru-ru/library/… - vitidev
  • Thanks, I didn’t know that there are already classes in c #. - Sanych Goilo

2 answers 2

Here are two questions:

What are the algorithms to encrypt an array of bytes (message) with this key?

Any symmetric algorithm will do; see, for example, the list here . This is what a combination of symmetric and asymmetric encryption can be used for:

  1. The client keeps the public key of asymmetric encryption
  2. The client comes up with a new password for symmetric encryption
  3. The client creates a message for the server, where the password, date and salt will be
  4. The client encrypts the packet with a public key and sends it to the server
  5. The server checks that the message is more or less new, the salt is correct, etc., remembers the password for symmetric encryption, creates a response message that everything is ok.
  6. The server encrypts this message using a symmetric algorithm and sends it to the client.

Everything, now the connection is established using the client password, the server has confirmed that it is it (for he knew the private key in step 5). Along the way, there are still subtleties of what salt to choose, etc.

Why do I need an iv array?

To enhance encryption. The fact is that if there are many duplicate characters in the message, the ratio of 0 to 1 is not 50/50, but something else, etc., then knowing this, it is possible in some cases to simplify hacking. The problem also arises if the block cipher works with an unaligned message, that is, if the block size is 64, and the message is 65 (that is, the last block will consist almost entirely of zeros). Similarly, two identical message blocks will have the same encrypted packets (see here). For this, a pseudo-random sequence is used, which helps remove correlations from the source text, aligning the ratio of 0 and 1, removing repetitions, etc. A simple random will be wrong here; they use cunning sequences, each element of which contains approximately the same number of zeros and ones.

  • Is vector a secret parameter? Knowing it can decode a message? - Sanych Goilo
  • No, it's not. I would advise using the RNGCryptoServiceProvider class (constructor without parameters) - it will already provide the necessary protection. - Manushin Igor
  • Why deceive? The initialization vector has nothing to do with alignment or randomization. - Pavel Mayorov

In order to encrypt a message using a session key, you can use any symmetric encryption algorithm.

The most popular are probably these:

  • RC4
  • 3DES
  • AES
  • "Grasshopper" (aka GOST)

The first two are fairly simple for self-implementation - but they are already outdated.

  • Please tell us why you need an initialization vector in AES? And should it be the same with encryption and decryption? - Sanych Goilo
  • @SanychGoilo too many letters for comment - Pavel Mayorov
  • so write the answer. - Sanych Goilo
  • @SanychGoilo so ask a new question - Pavel Mayorov