Home > Code, Cryptography, software, Tips and Tricks > Using BouncyCastle .NET library for elliptical curve cryptography

Using BouncyCastle .NET library for elliptical curve cryptography

Encryption is a process of modifying some information in such a way that only the intended person can understand it. In software world it is normally done using various encryption algorithms. DES, Triple DES, AES are just some example of encryption algorithms. But these algorithms suffer from a basic problem of handing keys. Your encrypted information is as safe as the key you used to encrypt it. If you have encrypted something, you sure want someone to decrypt it. And for that, you need to send him/her the key. If the communication media is safe to send the key, why don’t you just send the information without encryption.

Public key encryption solves the basic problem of handling and transferring keys. It uses different keys for encryption and decryption. Most widely used algorithm for public key encryption is RSA. But it has some problems:

  1. Encrypted text produced by RSA is pretty long.
  2. The size of encrypted data depends on the key size but a key size of 2048 bits is recommended if you see your software being used after 2010.
  3. This algorithm is pretty slow compared to other symmetric key algorithms such as DES, AES etc.

Elliptical curve cryptography is a type of public key encryption but it uses much shorter keys without compromising the encryption strength. Elliptical curve encryption done using 128 bit key gives the same level of security as given by RSA using 3072 bit key.

I needed to use elliptical curve encryption in one of my project and I was searching for its implementation on .NET platform and then I found Bouncy Castle.

That was just a little background. This post is really about using the Bouncy Castle library in a C# project. This library implements generating digital signatures using ECDSA.

Namespaces

Following namespaces will need to be used by us:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

Key Sizes

It is normally possible to use different key sizes. ECDSA supports following key sizes:

192 bit
239 bit
256 bit

Generating Keys

We can use the library itself to generate the random keys:

private static AsymmetricCipherKeyPair GenerateKeys (int keySize) {
var gen = new ECKeyPairGenerator ();
var secureRandom = new SecureRandom ();
var keyGenParam = new KeyGenerationParameters (secureRandom, keySize);
gen.Init (keyGenParam);
return gen.GenerateKeyPair ();
}

Generating Signature

private static AsymmetricCipherKeyPair GenerateKeys (int keySize) {
    var gen = new ECKeyPairGenerator ();
    var secureRandom = new SecureRandom ();
    var keyGenParam = new KeyGenerationParameters (secureRandom, keySize);
    gen.Init (keyGenParam);
    return gen.GenerateKeyPair ();
}

Verifying Signature

private static bool VerifySignature (AsymmetricCipherKeyPair key, string plainText, byte[] signature) {
    var encoder = new ASCIIEncoding ();
    var inputData = encoder.GetBytes (plainText);
    var signer = SignerUtilities.GetSigner ("ECDSA");
    signer.Init (false, key.Public);
    signer.BlockUpdate (inputData, 0, inputData.Length);

    return signer.VerifySignature (signature);
}

Putting It All Together

Now we just need a function which calls above function in the right sequence so that we can see whether it really works:

private static void ECDSASample (int keySize) {
    Console.WriteLine (string.Format ("======= Key Size: {0} =======", keySize));
    string s = "Hello World!";
    try {
        var key = GenerateKeys (keySize);
        var signature = GetSignature (s, key);
        var signatureOK = VerifySignature (key, s, signature);
        //Show it to me
        var pubicKey = (ECPublicKeyParameters)(key.Public);
        var privateKey = (ECPrivateKeyParameters)(key.Private);
        Console.WriteLine ("Input Text: " + s);
        Console.WriteLine ("Key ({0} bytes): {1}", privateKey.D.BitLength, privateKey.D);
        Console.WriteLine ("Signature ({0} bytes): {1}", signature.Length, ToString (signature));
        Console.WriteLine ("Signature verified: {0}", signatureOK);
        Console.WriteLine ();
    }
    catch (Exception ex) {
        Console.WriteLine (ex.Message);
    }
}

Calling the above function 3 times for all keys sizes shows:

======= Key Size: 192 =======
Input Text: Hello World!
Key (192 bytes): 5383271877913095293497459795960978936424465262977103383268
Signature (56 bytes):
303602190096736F03CB7AE4183590FE6185EFA900E6F4CD8B903100CF021900D5C0255ECC05921A9BC9EFD3AADB5B1FD8326CBA614713A3
Signature verified: True

======= Key Size: 239 =======
Input Text: Hello World!
Key (236 bytes): 83986687572262518000833780316201230289349432496423690059305652492588142
Signature (66 bytes): 3040021E0DABDA56D88E2DEB633FBA399EBBA5F5E678AE8600791EBF65094B0CDB0A021E381C2A864523F306D808FD45335EF73D62C9B66E9F6F6A846A9E7CA447D8
Signature verified: True

======= Key Size: 256 =======
Input Text: Hello World!
Key (255 bytes): 37067712327984319889067683157535631380322797492360190963255045782768937377579
Signature (71 bytes): 3045022100CFDB9F6DFB4C063C5C75CF4DCBC00F2CB79B61540BF982998C0F0810CAED7F2E022053DADF416C793AAB3EA8EB978A764B1E440C86C8BF897039EFCADEC7296790CA
Signature verified: True

Summary

I am still confused about a few points:

  1. Why it uses a key size of 239 bits. It seems so unnatural in binary world.
  2. If I increase the length on input text and generate the signature, I sometime get a signature with different length. For example key size of 192 generates signature of 56 bytes when I use the string “Hello World” but it generates the signature of 54 bytes with string “Hello World”.
  3. If I want to serialise the key to disk, which values actually should be saved.

You can download the source file if you wish.

Advertisements
  1. November 19, 2009 at 11:51 AM

    Great…Thank For Share This.

  2. Chris K
    January 26, 2010 at 9:10 PM

    Very useful guide to using BC with ECDSA – thanks.

    One small comment: your “Generating Signature” code appears to be a duplicate of the “Generating Keys” code – I assume this is a cut & paste error?

  3. Nish kala devi
    March 28, 2010 at 2:57 PM

    I dont how to implement this code
    please guide us
    to implement ECC

  4. rg
    April 14, 2010 at 8:24 PM

    Can we do( elliptical curve crypto) encryption and Decryption using this lib.
    Do you have any sample code to do the encryption and decryption.
    Thanks

  5. Pedro
    July 2, 2010 at 10:41 PM

    Hi,

    Is it possible in c# to verify a ECDSA signature with the public key (as a byte array), the signature and the data signed?
    Thanks

  6. Waw Rami
    February 19, 2011 at 5:59 PM

    Hi, all my gratitude for sharing this!
    pleas can u share some example about AES, SHA, MD5, RSA algorithm ?
    thx u !

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: