17

Please can you suggest any implementation of elliptical curve cryptography to be used on .NET platform?

Also if you have used them, can you tell me the recommended curves that should be used?

[EDIT]

As @FatCat mentioned, its implementation is available in .NET framework 3.5 but that is only available on windows vista. Can you please suggest another way/library to use it?

Mathias Brossard
  • 3,668
  • 2
  • 26
  • 30
Hemant
  • 19,486
  • 24
  • 91
  • 127

5 Answers5

13

The .NET Framework already includes Diffie-Hellman, which is an elliptic curve crypto algorithm. Look under System.Security.Cryptography.ECDiffieHellmanCng.

Justin R.
  • 23,435
  • 23
  • 108
  • 157
  • Great! I tried it but cant find how to use it to encrypt a message. Doesn't seem to have any "Encrypt" function...Documentation of new classes in framework 3.5 sucks. – Hemant Mar 27 '09 at 17:21
  • Oh and now i realise that this will work only on Windows Vista. – Hemant Apr 11 '09 at 17:37
  • 1
    the *Cng suffix means the crypto work is offloaded to Windows CNG (Crypto Next Gen) which is avail in Windows Vista and later. – Michael Howard-MSFT Apr 08 '10 at 15:46
  • 1
    Hemant: the documentation of framework 3.5 is not so bad; do you understand what Diffie-Hellman is? It is not used by itself for encryption, it is used to derive a secret, shared key to be used with a symmetric cipher from two parties using public key cryptography (including RSA or EC). – Hut8 Aug 11 '10 at 03:33
  • 1
    @Hemant ECDH is a key exchange system, you use it to derive symmetric keys for encryption – IanNorton Aug 22 '12 at 06:32
  • @bowenl2 and IanNorton: Not true, you can encrypt/decrypt the symmetric keys using encrypt(+sign)/decrypt(+verify) using the asymmetric keys. eg: Secure storage of AES key itself with seed of trust from the certificate private key. – DeepSpace101 Feb 02 '13 at 02:43
11

Check out the Bouncy Castle library for C#, it has ECDH and ECDSA.

Chochos
  • 5,155
  • 22
  • 27
  • Thanks Chochos. I have successfully used Bouncy Castle library. It was little difficult to find the documentation though! :) – Hemant Apr 18 '09 at 04:49
  • 1
    Last release for c# is 1.7, 7th April 2011, for Java 1.51, 27th July 2014. For c# projects I do not prefer Bouncy Castle, because of missing features and not maintained code. – hdev Jan 20 '15 at 08:13
  • 1
    Note that ECC in BouncyCastle for C# is very slow and likely vulnerable to timing attacks. – CodesInChaos Feb 10 '15 at 10:27
  • @CodesInChaos you've mentioned this several times on different questions related to ECC. Since you seem to be savvy regarding this area of cryptography, can you suggest an alternative library for C#? I'm looking to implement a DKG protocol, i.e. the key used to construct the cipher text is an aggregation of several parties public keys?? (remote trusted nodes), and ECC would seem to be an integral requirement for that. – Rebecca Nov 24 '20 at 13:08
3

The way you usually use ECC for encryption is by using "Ephemeral-Static Diffie-Hellman".

It works this way:

  • Take the intended receivers public key (perhaps from a certificate). This is the static key.
  • Generate a temporary ECDH keypair. This is the ephemeral keypair.
  • Use the keys to generate a shared symmetric key.
  • Encrypt the data with the symmetric key.
  • Transmit the encrypted data together with the public key from the ephemeral keypair.

The receiver can now use the ephemeral public key and his own static private key to recreate the symmetric key and decrypt the data.

You can read more in Standards for Efficient Cryptography: SEC 1: Elliptic Curve Cryptography section 5.1.3.

Rasmus Faber
  • 48,631
  • 24
  • 141
  • 189
  • The link you provided no longer points to the intended document. Instead, it takes you to blackberry.certicom.com page. – Thomas Nov 30 '18 at 13:30
3

Have a look at SecureBlackBox components

Rad
  • 8,336
  • 4
  • 46
  • 45
1

Great! I tried it but cant find how to use it to encrypt a message. Doesn't seem to have any "Encrypt" function

This the MSDN sample for 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);
                }
            }
        }
    }

}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
hdev
  • 6,097
  • 1
  • 45
  • 62