Click here to Skip to main content
15,868,016 members
Articles / Security / Encryption
Tip/Trick

Encryption and Decryption of Data using Elliptic Curve Cryptography( ECC ) with Bouncy Castle C# Library

Rate me:
Please Sign up or sign in to vote.
3.69/5 (13 votes)
13 Jan 2016CPOL3 min read 74.6K   17   16
If you want to know how to encrypt data using Elliptic Curve Algorithm in C#, then this tip is for you.

Introduction

This tip will help the reader in understanding how using C# .NET and Bouncy Castle built in library, one can encrypt and decrypt data in Elliptic Curve Cryptography.

Background

Before looking at the actual implementation, let's briefly understand some key elements.

Question: What is ECC?

Answer: ECC is an asymmetric cryptography algorithm which involves some high level calculation using mathematical curves to encrypt and decrypt data. It is similar to RSA as it's asymmetric but it uses a very small length key as compared to RSA.

Question: What is Bouncy Castle?

Answer: Bouncy Castle is an open source library in C# used for encryption. .NET has encryption classes but using Bouncy Castle makes your cryptography work quite easily.

Using the Code

In this tip, we will be writing code for the below mentioned steps of ECC.

ECC is an asymmetric cryptography algorithm which involves the following steps:

Encryption

  1. Define a Curve
  2. Generate public private Key pair using that curve, for both sender and receiver
  3. Generate a Shared secret key from the key pair
  4. From that shared secret key, generate an encryption key
  5. Using that encryption key and symmetric encryption algorithm, encrypt the data to send

Decryption

The sender will either share the curve with receiver or sender and receiver will have the same use for the same curve type. Also, sender will share its public key with receiver.

  1. Generate public private Key pair using the same curve for that curve. For receiver.
  2. Regenerate a shared secret key using private key of receiver and public key of sender.
  3. From that shared secret key, generate an encryption key
  4. Using that encryption key and symmetric encryption algorithm, decrypt the data

Now that we have gone through the steps, let's see each step with code.

Encryption Process

1: Define a Curve
C#
string curveName = "P-521";
var ecP1 = AnssiNamedCurves.GetByName("FRP256v1");
var ecP21 = TeleTrusTNamedCurves.GetByName("brainpoolp512t1");
X9ECParameters ecP = NistNamedCurves.GetByName(curveName);
c = (FpCurve)ecP.Curve;
eCDomainParameters = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
2: Generate public private Key pair using that curve. For Sender and receiver both
C#
senderPrivate = ((ECPrivateKeyParameters)asymmetricCipherKeyPair.Private).D.ToByteArray();
senderPublic = ((ECPublicKeyParameters)asymmetricCipherKeyPair.Public).Q.GetEncoded();
3: Generate a Shared secret key from the key pair
C#
public byte[]  GetSharedSecretValue(bool isEncrypt=true)
      {
          ECDHCBasicAgreement  eLacAgreement=new ECDHCBasicAgreement();
          eLacAgreement.Init(asymmetricCipherKeyPair.Private);
          ECDHCBasicAgreement  acAgreement=new ECDHCBasicAgreement();
          acAgreement.Init(asymmetricCipherKeyPairA.Private);
          BigInteger eLA=  eLacAgreement.CalculateAgreement(asymmetricCipherKeyPairA.Public);
          BigInteger a = acAgreement.CalculateAgreement(asymmetricCipherKeyPair.Public);
          if (eLA.Equals(a) && !isEncrypt)
          {
              return eLA.ToByteArray();
          }
          if (eLA.Equals(a) && isEncrypt)
          {
              return a.ToByteArray();
          }
          return null;
      }
4: From that shared secret key, generate an encryption key
C#
public byte[] DeriveSymmetricKeyFromSharedSecret(byte[] sharedSecret)
       {
           Org.BouncyCastle.Crypto.Agreement.Kdf.ECDHKekGenerator egH=
           		new ECDHKekGenerator( DigestUtilities.GetDigest("SHA256
           egH.Init(new DHKdfParameters(NistObjectIdentifiers.Aes,sharedSecret.Length,sharedSecret));
           byte[] symmetricKey = new byte[ DigestUtilities.GetDigest("SHA256").GetDigestSize()];
           egH.GenerateBytes(symmetricKey, 0,symmetricKey.Length);   

           return symmetricKey;
       }
5: Using that encryption key and symmetric encryption algorithm, encrypt the data to send
C#
public byte[] Encrypt(byte[] data, byte[] derivedKey)
        {
            byte[] output=null;
           try
           {
               KeyParameter keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey);
               IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING");
               cipher.Init(true, keyparam);
               try
               {
                 output = cipher.DoFinal(data);
                   return output;
               }
               catch (System.Exception ex)
               {
                   throw new CryptoException("Invalid Data");
               }
           }
           catch(Exception ex)
           {

           }

           return output;
       }

Decryption Process

The sender will either share the curve with receiver or sender and receiver will have same use for the same curve type. Also sender will share its public key with receiver.

1: Generate public private Key pair using the same curve for that curve. For receiver.
C#
asymmetricCipherKeyPairA = g.GenerateKeyPair();

           recieverPrivate = ((ECPrivateKeyParameters)asymmetricCipherKeyPairA.Private).D.ToByteArray();

           recieverPublic = ((ECPublicKeyParameters)asymmetricCipherKeyPairA.Public).Q.GetEncoded();
2: Regenerate a shared secret key using private key of receiver and public key of sender.
3: From that shared secret key, generate an encryption key
4: Using that encryption key and symmetric encryption algorithm, decrypt the data.
C#
public byte[] Decrypt(byte[] cipherData, byte[] derivedKey)
     {
          byte[] output=null;
         try
         {
             KeyParameter keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey);
             IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING");
             cipher.Init(false, keyparam);
             try
             {
                 output = cipher.DoFinal(cipherData);

             }
             catch (System.Exception ex)
             {
                 throw new CryptoException("Invalid Data");
             }
         }
         catch (Exception ex)
         {
         }

         return output;
     }

So, this is how we encrypt and decrypt a message in ECC.

Points of Interest

In order to first understand the working of ECC, I had to go through many specifications and Googling. Then, the main point and reason for me to write this tip is because there was nowhere on the internet where we could have a direct Bouncy Castle C# implementation of ECC given.

Although there is built-in .NET ECDiffieHellman class for ECC, I have not explored it because my main requirement was to use Bouncy Castle.

History

  • 13th January, 2016: First draft

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Syscom India
India India
.NET enthusiast and easy go lucky programmer with around 8 years of work experience in C# Winforms, Asp.net and WPF.
Most of the time you will find fiddling with code and when I don’t code I search for how to be physically fit for coding because after 8 years your back will not allow you to dive deep into your code for long hours

Comments and Discussions

 
QuestionFull code base Pin
Shirish Gadre19-Dec-21 4:50
Shirish Gadre19-Dec-21 4:50 
AnswerRe: Full code base Pin
ABDOL Ali9-Jun-23 2:06
ABDOL Ali9-Jun-23 2:06 
AnswerRe: Full code base Pin
ABDOL Ali9-Jun-23 2:06
ABDOL Ali9-Jun-23 2:06 
QuestionC# Implementation Pin
zikra ghulam23-Nov-20 21:02
zikra ghulam23-Nov-20 21:02 
QuestionNeed for C# full Code File Pin
Member 1291217015-Apr-19 2:40
Member 1291217015-Apr-19 2:40 
AnswerRe: Need for C# full Code File PinPopular
zikra ghulam23-Nov-20 21:43
zikra ghulam23-Nov-20 21:43 
QuestionEncryption and Decryption Pin
Abhimanyu Rawat17-Feb-16 1:40
Abhimanyu Rawat17-Feb-16 1:40 
GeneralMy vote of 4 Pin
JoshYates198015-Jan-16 4:46
professionalJoshYates198015-Jan-16 4:46 
BugWhy!? Pin
Timothy R14-Jan-16 17:17
Timothy R14-Jan-16 17:17 
GeneralRe: Why!? Pin
Mateen Khan15-Jan-16 0:17
Mateen Khan15-Jan-16 0:17 
GeneralRe: Why!? Pin
RobinHSanner4-Apr-17 6:48
RobinHSanner4-Apr-17 6:48 
GeneralRe: Why!? Pin
AlliedBits9-Dec-17 3:48
AlliedBits9-Dec-17 3:48 
QuestionWhy not use ECIES? Pin
AlliedBits14-Jan-16 6:43
AlliedBits14-Jan-16 6:43 
AnswerRe: Why not use ECIES? Pin
Mateen Khan15-Jan-16 0:13
Mateen Khan15-Jan-16 0:13 
GeneralGood Article. Pin
aarif moh shaikh13-Jan-16 23:17
professionalaarif moh shaikh13-Jan-16 23:17 
GeneralMy vote of 5 Pin
Franc Morales13-Jan-16 22:11
Franc Morales13-Jan-16 22:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.