19

Does anyone know of a simple tutorial or sample code of how to sign data in c# using bouncy castle. In Java there are tons of tutorials and samples. I can't find a single example in c#. Does anyone know how to do this?

w.donahue
  • 10,790
  • 13
  • 56
  • 78
  • Is there any reason you're wanting to use bouncycastle for this? .NET has it's own RSA encryption classes. – blowdart Jan 12 '12 at 18:33
  • I suppose that is a fair question. I have used BouncyCastle in Java in the past and know it worked with no problems compatibility wise to the backend I need to communicate with. Its possible the .Net version will as well, but it seems much less flexible and has much less options with paddings etc. – w.donahue Jan 12 '12 at 22:14
  • That makes sense - especially if you're worried about interop :) – blowdart Jan 13 '12 at 01:09
  • 1
    @blowdart The built in RSA encryption doesn't support loading a private key, it forces to bundle within the certificate, which is inappropriate for many purposes. – Alejandro Jul 10 '15 at 16:11

2 Answers2

43

Okay I could not find any documentation on how to do this. But I ended up figuring it out. I am pasting the full code here so hopefully it can help someone in the future.

This class will calculate a RSA signature with a sha1 hash for the provided string and verify it as well.

using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;

namespace API.Crypto
{
    public class RsaSha1Signing
    {
        private RsaKeyParameters MakeKey(String modulusHexString, String exponentHexString, bool isPrivateKey)
        {
            var modulus = new Org.BouncyCastle.Math.BigInteger(modulusHexString, 16);
            var exponent = new Org.BouncyCastle.Math.BigInteger(exponentHexString, 16);

            return new RsaKeyParameters(isPrivateKey, modulus, exponent);
        }

        public String Sign(String data, String privateModulusHexString, String privateExponentHexString)
        {
            /* Make the key */
            RsaKeyParameters key = MakeKey(privateModulusHexString, privateExponentHexString, true);

            /* Init alg */
            ISigner sig = SignerUtilities.GetSigner("SHA1withRSA");

            /* Populate key */
            sig.Init(true, key);

            /* Get the bytes to be signed from the string */
            var bytes = Encoding.UTF8.GetBytes(data);

            /* Calc the signature */
            sig.BlockUpdate(bytes, 0, bytes.Length);
            byte[] signature = sig.GenerateSignature();

            /* Base 64 encode the sig so its 8-bit clean */
            var signedString = Convert.ToBase64String(signature);

            return signedString;
        }

        public bool Verify(String data, String expectedSignature, String publicModulusHexString, String publicExponentHexString)
        {
            /* Make the key */
            RsaKeyParameters key = MakeKey(publicModulusHexString, publicExponentHexString, false);

            /* Init alg */
            ISigner signer = SignerUtilities.GetSigner("SHA1withRSA");

            /* Populate key */
            signer.Init(false, key);

            /* Get the signature into bytes */
            var expectedSig = Convert.FromBase64String(expectedSignature);

            /* Get the bytes to be signed from the string */
            var msgBytes = Encoding.UTF8.GetBytes(data);

            /* Calculate the signature and see if it matches */
            signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
            return signer.VerifySignature(expectedSig);
        }
    }
}
w.donahue
  • 10,790
  • 13
  • 56
  • 78
  • Can you comment on http://stackoverflow.com/questions/18344670/rsa-and-publickey-interop-with-dotnet – gpa Aug 20 '13 at 22:04
  • Well, finally. Somebody posted a clear instruction. Thanks a lot! – Vladimir Ivanov Mar 19 '14 at 10:55
  • Can any one tell what is privateModulusHexString and privateExponentHexString. I don't no about Bouncy castle. – Mallikarjun Aug 10 '17 at 13:22
  • @Mallikarjun Those are parts of the key that you are using to sign and validate your data. You need to already have a key created to use this code. So for example you privateModulusHexString would look something like this "14A1345B425C65457D856E3453F"... – w.donahue Aug 11 '17 at 14:29
  • @w.donahue Hi, can u please give me more information about privateModulusHexString and privateExponentHexString, I need it for the curve secp256r1 algorithm is ECDSA. If yes please tell me where do I get privateExponentHexString and privateExponentHexString The key was created with instructions based on those instructions https://stackoverflow.com/questions/19466907/c-sharp-ecdsa-signature-which-key-specification-can-i-choose Thanks! – Gradin98 Jan 15 '20 at 14:55
5

Look at Bouncy Castle web site. There is archive with sources and examples. http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-src-ext.zip

As a examples there are a lot of NUnit tests. Below is code of method to encrypt data byte array using RSA algorithm as a sample, but in Bouncy Castle sources and tests you can find more samples.

    public static byte[] Encrypt(byte[] data, AsymmetricKeyParameter key)
    {
        RsaEngine e = new RsaEngine();
        e.Init(true, key);
        int blockSize = e.GetInputBlockSize();
        List<byte> output = new List<byte>();

        for (int chunkPosition = 0; chunkPosition < data.Length; chunkPosition += blockSize)
        {
            int chunkSize = Math.Min(blockSize, data.Length - (chunkPosition * blockSize));
            output.AddRange(e.ProcessBlock(data, chunkPosition, chunkSize));
        }
        return output.ToArray();
    }
Regfor
  • 8,515
  • 1
  • 38
  • 51