Buona pratica vettoriale di inizializzazione AES

per la mia domanda Aes Encryption … manca un pezzo importante , ora ho imparato che il mio presupposto per la creazione di una crittografia reversibile su una stringa era un po ‘off. Ora ho

public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey) { var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt); using (var provider = new AesCryptoServiceProvider()) { provider.Key = encryptionKey; provider.Mode = CipherMode.CBC; provider.Padding = PaddingMode.PKCS7; using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV)) { using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { cs.Write(toEncryptBytes, 0, toEncryptBytes.Length); cs.FlushFinalBlock(); } return ms.ToArray(); } } } } 

e questo produce risultati coerenti; tuttavia, non sarà in grado di decodificare senza conoscere / impostare il vettore di inizializzazione. In realtà non voglio passare tre valori in questo metodo (su per la IV), che mi lascia con hardcoding l’IV o derivandolo dalla chiave. Mi piacerebbe sapere se questa è una buona pratica, o se renderà il valore crittografato vulnerabile ad attaccare in qualche modo … o sto davvero pensando troppo e dovrei semplicemente hardcode la IV?

AGGIORNAMENTO Il suggerimento di Per Iridium, ho provato invece qualcosa del genere:

  public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey) { if (string.IsNullOrEmpty(toEncrypt)) throw new ArgumentException("toEncrypt"); if (encryptionKey == null || encryptionKey.Length == 0) throw new ArgumentException("encryptionKey"); var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt); using (var provider = new AesCryptoServiceProvider()) { provider.Key = encryptionKey; provider.Mode = CipherMode.CBC; provider.Padding = PaddingMode.PKCS7; using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV)) { using (var ms = new MemoryStream()) { ms.Write(provider.IV, 0, 16); using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { cs.Write(toEncryptBytes, 0, toEncryptBytes.Length); cs.FlushFinalBlock(); } return ms.ToArray(); } } } } public static string DecryptString(byte[] encryptedString, byte[] encryptionKey) { using (var provider = new AesCryptoServiceProvider()) { provider.Key = encryptionKey; provider.Mode = CipherMode.CBC; provider.Padding = PaddingMode.PKCS7; using (var ms = new MemoryStream(encryptedString)) { byte[] buffer; ms.Read(buffer, 0, 16); provider.IV = buffer; using (var decryptor = provider.CreateDecryptor(provider.Key, provider.IV)) { using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { byte[] decrypted = new byte[encryptedString.Length]; var byteCount = cs.Read(decrypted, 0, encryptedString.Length); return Encoding.UTF8.GetString(decrypted, 0, byteCount); } } } } } 

tuttavia, questo mostra qualcosa di strano nel mio test unitario:

  [TestMethod] public void EncryptionClosedLoopTest() { var roundtrip = "This is the data I am encrypting. There are many like it but this is my encryption."; var encrypted = Encryption.EncryptString(roundtrip, encryptionKey); var decrypted = Encryption.DecryptString(encrypted, encryptionKey); Assert.IsTrue(roundtrip == decrypted); } 

il mio testo decodificato si presenta come “92ʪ F” , hpv0 sto crittografando. Ce ne sono molti come questo ma questa è la mia crittografia. “Che sembra quasi giusto ma, naturalmente, completamente sbagliato. Sembra che io sia vicino però. Mi manca un offset sul stream di memoria?