Posted on 16 Jun 2009 04:51 under c# code cryptography .net
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:
- Encrypted text produced by RSA is pretty long.
- 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.
- 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 http://stackoverflow.com/questions/690566/-net-implementation-libraries-of-elliptic-curve-cryptography 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 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); } }
Result
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 though:
- Why it uses a key size of 239 bits. It seems so unnatural in binary world.
- 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”.
- If I want to serialise the key to disk, which values actually should be saved.
Here is the complete source file.
Previous: Do you download ebooks from internet?
Hi,
Could you please post your code for the GetSignature
Thanks so much!
John
I am so grateful to read this such a wonderful post.
http://www.nikerbo.com
http://www.nikerko.com
http://www.nikerok.com
http://www.jordanhut.com
http://www.bestmonclerhut.com
Write very good! Back Up.
Discount Sunglasses http://www.bestsunglassesbrand.com
ray ban sunglasses http://www.sunglassko.com
Sunglasses for Glasses http://www.worstsunglassesbrand.com
Discount Nike Sneakers http://www.nikerwo.com
Buy Moncler Jackets http://frbestmoncler.com
hoe to use BouncyCastle library in console application in .NET
I don't want to generate private and public keys as I have my own. My question is how to use them?
Hi,
very good article.
Do you know if the above keys are compatible with secp256k1 or secp256r1, or similar, used in java bouncy castle ECDSA library?
Maybe are compatible with prime256v1?
It's important for me to verify ECDSA signature (C# side generated) under java/android applications
Thanks in advance
can we store encrypted text or can we display encrypted text as it is in byte array?
plzzz help with a code to display encrypted text
Hi, please provide the GetSignature method also… Why would you post something incomplete?
Sorry my mistake didn't see the "Here is the complete source file." :) thanks!
Post preview:
Close preview