Voglio usare una crittografia ibrida nella mia applicazione, quindi dopo aver letto un sacco di righe ho finito con questa implementazione, per favore lo crititi;) (Voglio attenermi a .Net)
byte[] aesKey = GetRandomBytes(256); // 256 Bits with RNGCryptoServiceProvider
byte[] aesIV = GetRandomBytes(128); // 128 Bits with RNGCryptoServiceProvider
Domanda: Dovrei crittografare l'IV, a mio avviso questo sarebbe solo l'oscurità attraverso la segretezza e non aggiungere nulla alla mia secrità.
Ora crittografo aesKey e aesIV con ogni PublicKey (Recipient).
foreach (RSACryptoServiceProvider key in keys)
{
var data = new EncryptedData();
data.Data = key.Encrypt(bytes, true); // with OAEP padding
data.Fingerprint = CreateFingerprint(key); // SHA1 from the public key
list.Add(data);
}
Domanda: se non si memorizza l'impronta digitale, è trattabile?
Domanda: ho letto che il padding sbagliato potrebbe essere un problema di sicurezza, ma cosa succede se criptico una chiave aes casuale?
Se un 'segno' passato == true 'Firmo i dati con ogni PrivateKey (Sender), in caso normale una chiave.
if (sign)
{
foreach (RSACryptoServiceProvider key in privateKeys)
{
var hash = new SHA512Managed();
byte[] hashBytes = hash.ComputeHash(data);
byte[] signHash = key.SignHash(hashBytes, CryptoConfig.MapNameToOID("SHA512"));
var item = new EncryptedData
{
Data = signHash,
Fingerprint = CreateFingerprint(key)
};
encryptedData.Signatures.Add(item);
}
}
Domanda: RSACryptoServiceProvider.SignHash rappresenta il metodo giusto? (O SignData?)
Domanda: Trovo approcci diversi, alcuni vogliono firmare i dati semplici e altri crittografati. Cosa ne pensi?
Ora crittografo i dati effettivi
using (var rijAlg = new RijndaelManaged())
{
rijAlg.KeySize = 256;
rijAlg.Key = aesKey;
rijAlg.IV = aesIV;
rijAlg.Mode = CipherModeTextMode; // CipherMode.CBC
rijAlg.Padding = PaddingModeTextMode; // PaddingMode.ISO10126, pad with random data
using (var stream = new MemoryStream())
using (ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV))
using (var encrypt = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
{
encrypt.Write(data, 0, data.Length);
encrypt.FlushFinalBlock();
return stream.ToArray();
}
}
Alla fine searlize questo oggetto e invio a Bob.
public class EncryptedDataHolder
{
public IEnumerable<EncryptedData> EncryptedAesKeys { get; set; }
public IEnumerable<EncryptedData> EncryptedAesIVs { get; set; }
public IEnumerable<EncryptedData> Signatures { get; set; }
public byte[] EncryptedContent { get; set; }
}
public class EncryptedData
{
public byte[] Data { get; set; }
public byte[] Fingerprint { get; set; }
}
Domanda: aggiungere / rimuovere informazioni?
Ho visto questo grafico su link
link
Quindi penso che dovrei usare una chiave RSA a 16384 bit per soddisfare il livello di sicurezza di aes 256. Funziona con csp = new RSACryptoServiceProvider(16384);
ma richiede alcuni minuti.
Domanda: Questo approccio è ragionevole?
Grazie mille!