Implementación.NET(librerías) de criptografía de curva elíptica
encryption cryptography (5)
¡Genial! Lo intenté pero no encuentro cómo usarlo para cifrar un mensaje. No parece tener ninguna función de "Encriptar"
Este es el ejemplo de MSDN para System.Security.Cryptography.ECDiffieHellmanCng
.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class Alice
{
public static byte[] alicePublicKey;
public static void Main(string[] args)
{
using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng())
{
alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
alice.HashAlgorithm = CngAlgorithm.Sha256;
alicePublicKey = alice.PublicKey.ToByteArray();
Bob bob = new Bob();
CngKey k = CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob);
byte[] aliceKey = alice.DeriveKeyMaterial(CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob));
byte[] encryptedMessage = null;
byte[] iv = null;
Send(aliceKey, "Secret message", out encryptedMessage, out iv);
bob.Receive(encryptedMessage, iv);
}
}
private static void Send(byte[] key, string secretMessage, out byte[] encryptedMessage, out byte[] iv)
{
using (Aes aes = new AesCryptoServiceProvider())
{
aes.Key = key;
iv = aes.IV;
// Encrypt the message
using (MemoryStream ciphertext = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ciphertext, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
byte[] plaintextMessage = Encoding.UTF8.GetBytes(secretMessage);
cs.Write(plaintextMessage, 0, plaintextMessage.Length);
cs.Close();
encryptedMessage = ciphertext.ToArray();
}
}
}
}
public class Bob
{
public byte[] bobPublicKey;
private byte[] bobKey;
public Bob()
{
using (ECDiffieHellmanCng bob = new ECDiffieHellmanCng())
{
bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
bob.HashAlgorithm = CngAlgorithm.Sha256;
bobPublicKey = bob.PublicKey.ToByteArray();
bobKey = bob.DeriveKeyMaterial(CngKey.Import(Alice.alicePublicKey, CngKeyBlobFormat.EccPublicBlob));
}
}
public void Receive(byte[] encryptedMessage, byte[] iv)
{
using (Aes aes = new AesCryptoServiceProvider())
{
aes.Key = bobKey;
aes.IV = iv;
// Decrypt the message
using (MemoryStream plaintext = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(plaintext, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(encryptedMessage, 0, encryptedMessage.Length);
cs.Close();
string message = Encoding.UTF8.GetString(plaintext.ToArray());
Console.WriteLine(message);
}
}
}
}
}
¿Puede sugerir alguna implementación de criptografía de curva elíptica para usar en la plataforma .NET?
Además, si los ha usado, ¿puede decirme las curvas recomendadas que deben usarse?
[EDITAR]
Como mencionó @FatCat, su implementación está disponible en .NET framework 3.5, pero solo está disponible en Windows Vista. ¿Puede por favor sugerir otra forma / biblioteca para usarlo?
.NET Framework ya incluye Diffie-Hellman, que es un algoritmo criptográfico de curva elíptica. Busque en System.Security.Cryptography.ECDiffieHellmanCng .
Echa un vistazo a la biblioteca Bouncy Castle para C #, tiene ECDH y ECDSA.
Echa un vistazo a los componentes SecureBlackBox
La forma en que usualmente usas ECC para el cifrado es mediante el uso de "Ephemeral-Static Diffie-Hellman".
Funciona de esta manera:
- Tome la clave pública del receptor (tal vez de un certificado). Esta es la clave estática.
- Generar un par de llaves ECDH temporal. Este es el par de llaves efímero.
- Usa las teclas para generar una clave simétrica compartida.
- Cifrar los datos con la clave simétrica.
- Transmita los datos cifrados junto con la clave pública desde el par de claves efímero.
El receptor ahora puede usar la clave pública efímera y su propia clave privada estática para recrear la clave simétrica y descifrar los datos.
Puede leer más en Estándares para la criptografía eficiente: SEC 1: Criptografía de curva elíptica, sección 5.1.3.