whoami
whoami

Reputation: 123

How to do signature using SHA256withRSA algorithm in C#

I tried search solution to my query, I couldn't able find match I am looking for, this is very basic, but to my better understanding I am posting below query.

I want to encode and do signature for my string using "SHA256withRSA" algorithm. I could able to see lot of sample code in java using "SHA256withRSA" but in C# I could see first we are hashed data using SHA256 then we are sign hash using RSACryptoServiceProvider.

My questions are:

  1. In C# we have separate algorithm of "SHA256withRSA", If yes, help with sample code.

  2. If no then what would be better approach to achieve it in C#?

Upvotes: 6

Views: 20487

Answers (3)

Damnjan Markovic
Damnjan Markovic

Reputation: 37

public static string EncryptMessage(string message, string keyLocation) 
{ 
    byte[] encryptedData; 
    using (System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider()) 
    { 
        using (var stream = File.OpenRead(keyLocation)) 
            { 
                using (var reader = new PemUtils.PemReader(stream)) 
                { 
                System.Security.Cryptography.RSAParameters rsaParameters = reader.ReadRsaKey(); 
                rsa.ImportParameters(rsaParameters); 
                } 
            } 
        byte[] dataToEncrypt = System.Text.Encoding.UTF8.GetBytes(message); 
        encryptedData = rsa.SignData(dataToEncrypt, new System.Security.Cryptography.SHA256CryptoServiceProvider()); 
    }
    return Convert.ToBase64String(encryptedData); 
}

Upvotes: 0

anhtuangv
anhtuangv

Reputation: 575

First of all, you need a key pairs. To generate a key pairs you can do as the following and using OpenSSL:

  1. Generate a private key

    openssl genrsa -out my-private-key.pem 2048

  2. Generate a public cert

    openssl req -new -key my-private-key.pem -x509 -days 36500 -out my-public-cert.pem

  3. Generate a p12 file

    openssl pkcs12 -export -in my-public-cert.pem -inkey my-private-key.pem -out my-key-pairs.p12

Now you can use the following sample code in C#.NET to create a digital signature and verify a digital signature

    public static string SignData(byte[] data, string pkcs12File, string pkcs12Password)
    {
        X509Certificate2 signerCert = new X509Certificate2(pkcs12File, pkcs12Password, X509KeyStorageFlags.Exportable);
        RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider();
        rsaCSP.FromXmlString(signerCert.PrivateKey.ToXmlString(true));
        var SignedData = rsaCSP.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
        return Convert.ToBase64String(SignedData);
    }

    public static bool VerifySignature(byte[] data, string signature, string publicCert)
    {
        X509Certificate2 partnerCert = new X509Certificate2(publicCert);
        RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)partnerCert.PublicKey.Key;
        return rsaCSP.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), Convert.FromBase64String(signature));
    }

Remember that your project need to add reference to System.Security

Upvotes: 7

bartonjs
bartonjs

Reputation: 33088

Do not use RSACryptoServiceProvider unless you are doing interop with CAPI, like opening a named key.

To do RSA signing with SHA-(2-)256:

byte[] signature = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

You can get the RSA object from a cert:

using (RSA rsa = cert.GetRSAPrivateKey())
{
    ...
}

Or you can make one up from existing RSA parameters:

using (RSA rsa = RSA.Create(rsaParameters))
{
   ...
}

Or you can make up a new key from nothing:

using (RSA rsa = RSA.Create(2048))
{
    // you’ll need to save the parameters somewhere to have a stable key
    rsaParameters = rsa.ExportParameters(true));
    ...
}

Upvotes: 7

Related Questions