Ich versuche zu verstehen, wie man einen Initialisierungsvektor und das Salz (wenn anwendbar) behandelt und verwaltet, wenn Daten mit einem symmetrischen Verschlüsselungsalgorithmus, in diesem Fall AES, verschlüsselt und entschlüsselt werden.Symmetrische Verschlüsselung (AES): Ist das Speichern von IV und Salz neben den verschlüsselten Daten sicher und ordnungsgemäß?
Ich habe von verschiedenen SO-Threads und verschiedenen anderen Websites abgeleitet, dass weder die IV noch das Salz geheim sein müssen, nur einmalig, um sich gegen kryptoanalytische Angriffe wie einen Brute-Force-Angriff zu verteidigen. In Anbetracht dessen dachte ich, dass es sinnvoll wäre, meine Pseudozufalls-IV mit den verschlüsselten Daten zu speichern. Ich frage, ob die Methode, die ich benutze, richtig ist, und sollte ich mein hart codiertes Salz auf die gleiche Weise behandeln? Unter diesen Umständen ist es dem Speicherstrom an der Seite des IV
Mein Code zu schreiben:
private const ushort ITERATIONS = 300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };
private static byte[] CreateKey(string password, int keySize)
{
DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
return derivedKey.GetBytes(keySize >> 3);
}
public static byte[] Encrypt(byte[] data, string password)
{
byte[] encryptedData = null;
using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
{
provider.GenerateIV();
provider.Key = CreateKey(password, provider.KeySize);
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
using (MemoryStream memStream = new MemoryStream(data.Length))
{
memStream.Write(provider.IV, 0, 16);
using (ICryptoTransform encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
{
using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
}
}
encryptedData = memStream.ToArray();
}
}
return encryptedData;
}
public static byte[] Decrypt(byte[] data, string password)
{
byte[] decryptedData = new byte[data.Length];
using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
{
provider.Key = CreateKey(password, provider.KeySize);
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
using (MemoryStream memStream = new MemoryStream(data))
{
byte[] iv = new byte[16];
memStream.Read(iv, 0, 16);
using (ICryptoTransform decryptor = provider.CreateDecryptor(provider.Key, iv))
{
using (CryptoStream cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
{
cryptoStream.Read(decryptedData, 0, decryptedData.Length);
}
}
}
}
return decryptedData;
}
Ich bin auch offen für alle anderen Informationen über die symmetrische Verschlüsselung in Bezug auf die richtige Praxis.
Wenn Sie sie nicht mit Ihren verschlüsselten Daten speichern, müssen Sie sie irgendwo speichern - also YMMV. – larsw
Im CBC-Modus fungiert jeder verschlüsselte Block als IV des nächsten Blocks, sodass IV als öffentlicher Wert nicht sicherheitsrelevant sein kann - andernfalls wäre der CBC-Betriebsmodus nicht sicher. :) – vhallac
@vhallac gut, mehr das V (Vektor) als die IV (Initialisierungsvektor) ist, kann natürlich nur die erste sein. –