Click here to Skip to main content
13,731,634 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

34K views
16 bookmarked
Posted 13 Jan 2016
Licenced CPOL

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

, 13 Jan 2016
Rate this:
Please Sign up or sign in to vote.
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
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
senderPrivate = ((ECPrivateKeyParameters)asymmetricCipherKeyPair.Private).D.ToByteArray();
senderPublic = ((ECPublicKeyParameters)asymmetricCipherKeyPair.Public).Q.GetEncoded();
3: Generate a Shared secret key from the key pair
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
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
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.
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.
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)

Share

About the Author

Mateen Khan
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

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionEncryption and Decryption Pin
Abhimanyu Rawat17-Feb-16 1:40
memberAbhimanyu 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
memberTimothy R14-Jan-16 17:17 
GeneralRe: Why!? Pin
Mateen Khan15-Jan-16 0:17
memberMateen Khan15-Jan-16 0:17 
GeneralRe: Why!? Pin
RobinHSanner4-Apr-17 6:48
memberRobinHSanner4-Apr-17 6:48 
GeneralRe: Why!? Pin
AlliedBits9-Dec-17 3:48
groupAlliedBits9-Dec-17 3:48 
QuestionWhy not use ECIES? Pin
AlliedBits14-Jan-16 6:43
groupAlliedBits14-Jan-16 6:43 
AnswerRe: Why not use ECIES? Pin
Mateen Khan15-Jan-16 0:13
memberMateen 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
memberFranc 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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05-2016 | 2.8.180920.1 | Last Updated 13 Jan 2016
Article Copyright 2016 by Mateen Khan
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid