title: How to properly implement AES encryption with .net core 2?
body: <p>For some reason, I've been asked to implement some basic encryption to secure a specific value transmitted to the client (depending on the client).</p>
  <p>Context is: we are the one who generate the encrypted key, we pass that encrypted key to the client, and the client will never have to decrypt it (but we will have to in backend)</p>
  <p>Example =&gt; we give the encrypted key &quot;123ABCDE==&quot; to the client. The client calls our API passing data + that encrypted key, like:</p>
  <pre><code>{
  &quot;encKey&quot;: &quot;123ABCDE==&quot;,
  &quot;payload&quot;: &quot;somedatahere&quot;
  }
  </code></pre>
  <p>Then we decrypt the key, if it matches a specific value in DB (again, depending on client), we continue with some other operations.</p>
  <p>So, I decided to go with AES encryption. Following is what I have for now.</p>
  <h1>definition of the key information:</h1>
  <pre><code>public class KeyInfo
  {
      public byte[] Key { get; }
      public byte[] Iv { get; }
      
      public KeyInfo()
      {
          using (var myAes = Aes.Create())
          {
              Key = myAes.Key;
              Iv = myAes.IV;
          }
      }
  
      public KeyInfo(string key, string iv)
      {
          Key = Convert.FromBase64String(key);
          Iv = Convert.FromBase64String(iv);
      }
  }
  </code></pre>
  <h1>the encryption method</h1>
  <pre><code> private static byte[] Encrypt_AES(string plainText, byte[] key, byte[] iv)
          {
              if (plainText == null || plainText.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(plainText));
              if (key == null || key.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(key));
              if (iv == null || iv.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(iv));
              byte[] encrypted;
  
              using (var aesAlgo = Aes.Create())
              {
                  aesAlgo.Key = key;
                  aesAlgo.IV = iv;
                 
                  var encryptor = aesAlgo.CreateEncryptor(aesAlgo.Key, aesAlgo.IV);
                  using (var msEncrypt = new MemoryStream())
                  {
                      using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                      {
                          using (var swEncrypt = new StreamWriter(csEncrypt))
                          {
                              swEncrypt.Write(plainText);
                          }
  
                          encrypted = msEncrypt.ToArray();
                      }
                  }
  
              }
  
              return encrypted;
          }
  </code></pre>
  <h1>the decryption method:</h1>
  <pre><code>private static string Decrypt_AES(byte[] cipherText, byte[] key, byte[] iv)
          {
              if (cipherText == null || cipherText.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(cipherText));
              if (key == null || key.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(key));
              if (iv == null || iv.Length &lt;= 0)
                  throw new ArgumentNullException(nameof(iv));
  
              string plaintext;
              using (var aesAlgo = Aes.Create())
              {
                  aesAlgo.Key = key;
                  aesAlgo.IV = iv;
  
                  var decryptor = aesAlgo.CreateDecryptor(aesAlgo.Key, aesAlgo.IV);
                  using (var msDecrypt = new MemoryStream(cipherText))
                  {
                      using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                      {
                          using (var srDecrypt = new StreamReader(csDecrypt))
                          {
                              plaintext = srDecrypt.ReadToEnd();
                          }
                      }
                  }
              }
  
              return plaintext;
          }
      }
  </code></pre>
  <h1>the key and IV stored in appsettings.json:</h1>
  <pre><code>&quot;EncryptionKey&quot;: &quot;myEncryptionKeyHere&quot;,
  &quot;EncryptionInitialVector&quot;: &quot;myInitialVectorHere&quot;,
  </code></pre>
  <h1>the registration in Satrtup.cs</h1>
  <pre><code>services.AddTransient(ec =&gt; new EncryptionService(new KeyInfo(appSettings.EncryptionKey, appSettings.EncryptionInitialVector)));
  </code></pre>
  <p>I have a few question about all of this.</p>
  <ul>
  <li>is AES rh right choice for my needs?</li>
  <li>is the way it is implemented here correct?</li>
  <li>where should I store the Key and IV ? (not sure appsettings.json is okay)</li>
  <li>how do I generate the Key and IV ? Is there tools for that?</li>
  </ul>
  <p>Thanks for reading!</p>
  <p>EDIT:</p>
  <blockquote>
  <p>You say &quot;we are the one who generate the encrypted key, we pass that
  encrypted key to the client&quot; - how does that happen securely?</p>
  </blockquote>
  <p>-&gt; The client will have to connect to his account where he could access that <code>encKey</code>.</p>
  <p>So, reading <code>@vcsjones</code> answer, AES may not be the right thing to implement here. Since I don't want to store the IV on database, if the client loses it, it means he would have to generate another key, with another IV, and change the <code>encKey</code> in all applications.</p>
  <p>Would an asymetric encryption be better? If I understood correctly, it would mean to encrypt the value with a private key, give that encrypted value to the client + the public key (which would be the same for every client?)</p>