Il codificatore AES manipola solo la prima parte dei dati di input utilizzando il vettore di inizializzazione

Il codificatore AES manipola solo la prima parte dei dati di input utilizzando il vettore di inizializzazione

La soluzione per il crittografo AES modifica solo la prima parte dei dati di input utilizzando il vettore di inizializzazione
di seguito:

Considera il seguente codice (puoi anche controllare in sandbox):

using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

class EncryptionIVTest
{
    private static readonly string Data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    private static readonly byte[] Password = Guid.NewGuid().ToByteArray().Take(32).ToArray();

    static void Main()
    {
        var iv = Guid.NewGuid().ToByteArray().Take(16).ToArray(); // random initialization vector
        var iv2 = new byte[16]; // just another zero-filled initialization vector
        var encrypted = Encrypt(iv);

        Console.WriteLine($"Original: {Data}");
        Console.WriteLine($"Encrypted: {encrypted}");
        Console.WriteLine($"Decrypted: {Decrypt(encrypted, iv)}");
        Console.WriteLine($"Decrypted with another IV: {Decrypt(encrypted, iv2)}"); // It should throw exception or output completely mangled string
    }

    private static string Encrypt(byte[] iv)
    {
        var cipher = CreateCipher(iv);
        var buf = Encoding.UTF8.GetBytes(Data);
        using var ms = new MemoryStream();
        using (var stream = new CryptoStream(ms, cipher.CreateEncryptor(), CryptoStreamMode.Write))
            stream.Write(buf, 0, buf.Length);
        return Convert.ToBase64String(ms.ToArray());
    }

    private static string Decrypt(string encrypted, byte[] iv)
    {
        var cipher = CreateCipher(iv);
        using var ms = new MemoryStream(Convert.FromBase64String(encrypted));
        using var result = new MemoryStream();
        using (var stream = new CryptoStream(ms, cipher.CreateDecryptor(), CryptoStreamMode.Read))
            stream.CopyTo(result);
        return Encoding.UTF8.GetString(result.GetBuffer(), 0, (int)result.Length);
    }

    private static Aes CreateCipher(byte[] iv)
    {
        var cipher = Aes.Create();
        cipher.Key = Password;
        cipher.IV = iv;
        cipher.Mode = CipherMode.CBC;
        return cipher;
    }
}

Emette:

Original: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Encrypted: EROKh8lVgREvTqzBYXjEm7EbTIT883uR9wsD82lRM14KtiOYr+/+ZpAwz/UfprqSP5mIQ7Du/d43Y88hAPjvkA==
Decrypted: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Decrypted with another IV: [email protected]?n? ??7║??Paaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

La quarta stringa non è completamente storpiata, contiene una scia intatta. Sembra che il codificatore rovini solo i primi 16 byte (dimensione di un vettore di inizializzazione) e lascia altri intatti. Per impostazione predefinita, il crittografo utilizza CBC CipherMode e dovrebbe alterare tutti i dati se ho capito correttamente.

È possibile manipolare tutti i dati, non solo la prima parte?

Lo scopo dell'IV non è "distorcere" ulteriormente i dati o fungere da seconda chiave di crittografia, il che renderebbe semplicemente ridondante la chiave effettiva.

Lo scopo è fornire ulteriore entropia in modo che due set di dati in chiaro crittografati con la stessa chiave ma con IV diversi appaiano completamente diversi quando crittografati. Ciò rende più difficile per un utente malintenzionato dedurre qualsiasi cosa sui dati. Ad esempio, senza l'IV, aggressori sofisticati potrebbero eseguire analisi statistiche basate su modelli linguistici e potenzialmente capire quali sono effettivamente determinati pacchetti crittografati in base alla frequenza con cui si verificano.

Quindi quello che stai vedendo non dovrebbe essere sorprendente o preoccupante. L'IV sta facendo il suo lavoro.

A proposito, usare un Guid come chiave NON è sicuro. Prima di tutto sono solo 16 byte e non 32, quindi in pratica hai solo una chiave a 128 bit. Vedere https://docs.microsoft.com/en-us/dotnet/standard/security/generating-keys-for-encryption-and-decryption#symmetric-keys per le API corrette da utilizzare per generare chiavi e IV