C# – How to fix “Invalid algorithm specified” when signing with SHA256

A digital signature or digital signature scheme is a mathematical scheme for demonstrating the authenticity of a digital message or document. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, and that it was not altered in transit. Digital signatures are commonly used for software distribution, financial transactions, and in other cases where it is important to detect forgery or tampering (From Wikipedia)”. If you are now working in information security fields, you should be familiar with this concept. Since version .Net Framework 3.5 SP1, Microsoft has supported for signing and verifing digital signature with SHA256. However maybe you’ll get an error “Invalid algorithm specified” if trying to sign data with SHA256. To reproduce the error, I would like to make a demo of code for signing with SHA256 in the code below

static void Main(string[] args)
{
	try
	{
		X509Store storeMyCurrentUser = new X509Store(StoreName.My, StoreLocation.CurrentUser);
		storeMyCurrentUser.Open(OpenFlags.MaxAllowed);

		X509Certificate2 certRCA = new X509Certificate2(@"C:\OpenSSL-Win64\bin\RCA.p12");
		if (!storeMyCurrentUser.Certificates.Contains(certRCA))
			storeMyCurrentUser.Add(certRCA);
		RSACryptoServiceProvider _provider = null;
		byte[] data = new byte[] { 0, 1, 2, 3, 4, 5 };
		if (certRCA.HasPrivateKey)
		{
			_provider = (RSACryptoServiceProvider)certRCA.PrivateKey;
			byte[] sigedBytes = _provider.SignData(data, "SHA256");
		}
		storeMyCurrentUser.Close();
		Console.WriteLine("Finished");
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}
	Console.ReadLine();
}

The “Invalid algorithm specified” can occur at line

byte[] sigedBytes = _provider.SignData(data, "SHA256");

The reason is that RSACryptoServiceProvider relies on the underlying CryptoAPI to do its work. This feature will only be enabled on versions of Windows which support SHA256 algorithms in CrytoAPI. That mean it depends on the CSP (Cryptographic Service Provider) that we use to perform the cryptographic operations. When we call SignData with SHA256, because the Microsoft CSPs are implemented on Rsaenh.dll, the function CryptCreateHash will be called behind the scenes with ALG_ID of CALG_SHA_256. This crypto API doesn’t perform crypto operations by itself. It redirects the parameters which it gets from application to the desired CSP, and the CSP performs the operations on its behalf. So the error we are getting is actually coming from the CSP.
Therefore to check if we can use SHA256, we must be sure that:
– Your certificate must be generated with support for SHA256.
– Your CSP which you use to generate your certificate must support SHA256.

If you want to understand more about certificate and PKI system, there is an expensive book which covers a lof of security problems on Windows Server Windows Server 2008 PKI and Certificate Security (PRO-Other)

1. How to check if my certificate was generated with SHA256 support
– For applying a certificate which is valid over internet, we should create a Certificate Request and then send this request to a root CA (Certificate Authority) like Verisign to generate a valid certificate for us.
– On the root CA, he’ll create himself a pair key-cert to validate all other certificates like this

openssl req -new -newkey rsa:1024 -days 365 -extensions v3_ca -subj "/C=VN/ST=SG/L=SaiGon/O=SuperVerisign/OU=RootCA/CN=SuperVerisignRootCA/" -nodes -x509 -sha256 -set_serial 0 -keyout RootCA.key -out RootCA.cert

– On our sides, to apply for a new certificate, we create a pair key-request and then send certificate request file (.csr) to root CA.

openssl req -newkey rsa:1024 -subj "/C=DE/ST=BY/L=Munich/O=Rongchaua/OU=Home/CN=RongchauaHome/" -nodes -sha256 -keyout RCA.key -out RCA.csr

– When a root CA receives our Certificate Request, he’ll generate a cert with a validity of one year or many years and many other options according to our request which you can see at the documentation of OpenSSL.

openssl x509 -req -sha256 -CAcreateserial -in RCA.csr -days 365 -CA RootCA.cert -CAkey RootCA.key -out RCA.cert

– In the command of OpenSSL above you can see that our cert was generated with sha256 support. If root CA does not support this option, we cannot use SHA256 to sign data because it is not supported inside the certificate. To check if your certificate supports SHA256, you can see use this command

openssl x509 -in RCA.cert -text -noout

– The content of cert file looks something like this. It’s important that Signature Algorithm: sha256WithRSAEncryption

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            d4:d6:e0:82:70:e4:32:e8
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=VN, ST=SG, L=SaiGon, O=SuperVerisign, OU=RootCA, CN=SuperVerisignRootCA
        Validity
            Not Before: Jul 25 09:23:16 2011 GMT
            Not After : Jul 24 09:23:16 2012 GMT
        Subject: C=DE, ST=BY, L=Munich, O=Rongchaua, OU=Home, CN=RongchauaHome
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:dd:93:51:76:c9:9b:f4:6e:ad:a1:5d:76:b6:78:
                    0a:d6:83:b8:8e:53:05:f0:a0:39:18:fa:9b:ad:1b:
                    fc:7b:0a:0e:6a:b0:a1:88:49:6a:a0:ce:38:fd:5a:
                    08:6a:4d:ea:24:74:d9:84:49:43:d3:a8:00:d4:e2:
                    c3:c4:c7:75:e3:85:a6:b2:42:d9:8a:73:8a:04:8c:
                    c8:2b:0a:79:e9:a9:b4:42:d1:49:d3:39:77:ca:5f:
                    53:4e:47:0c:6b:0e:41:2d:13:d2:5d:3a:f1:d1:0c:
                    8d:82:6d:b8:6c:a7:66:fb:53:98:37:9c:54:c0:9c:
                    3b:5c:23:db:e4:fe:0d:cf:9f
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
        c9:b5:20:e8:8f:ae:e6:3b:dc:82:4f:6f:c3:ce:96:6d:93:52:
        21:c0:da:e5:96:75:f0:e9:71:d2:41:76:00:ba:e8:a0:d3:5b:
        69:56:35:52:3d:dd:74:33:0b:59:4b:db:7a:91:48:32:30:f4:
        ab:10:19:fc:79:55:d2:bf:a9:d1:ec:cb:5e:ea:a9:38:a4:b0:
        a4:f1:4b:2c:d1:9f:92:a0:4b:66:30:52:c6:55:39:5c:3f:77:
        b2:d7:7a:a8:23:c8:1d:8d:e6:a4:72:b6:7b:57:75:da:0c:26:
        19:1c:a7:24:60:ef:cf:7f:c7:da:0b:ec:e1:b7:66:6a:cd:32:
        fb:04

2. How do I know that CSP of my certificate supports SHA256?
– After you receive the cert file from root CA, maybe you would like to integrate your private key into your cert to sign/verify data. If you are using 3rd party CSP to sign/verify your data, I recommend you to contact the provider directly and ask if they support SHA256. For the other who uses Microsoft CSP, to check if your Windows computer supports Microsoft CSP with SHA256, open your Command Prompt, enter “napclcfg.msc” to open “NAP Client Configuration”.
– Browse on the left TreeView to “Health Registration Settings” –> “Request Policy”, then click on “Cryptographic Service Provider” to list all supported Microsoft Cryptographic Service Providers.

Cryptographic Service Provider

– These entries are stored in registry under HKLM\Software\Microsoft\Cryptography\Defaults\Provider as image below

Cryptographic Service Provider

– There is another registry key at the same level of this key is “Provider Types”. Click on all these types you’ll see the name of the provider and his supported Protocol. For example, Type 001 – Microsoft Strong Cryptographic Provider – RSA Full (Signature and Key Exchange). Because we want to use SHA256 for hashing, we need Type 024 – Microsoft Enhanced RSA and AES Cryptographic Provider – RSA Full and AES.

– Now we can integrate our private keys with our certificate and indicate explicitly that we would like to use “Microsoft Enhanced RSA and AES Cryptographic Provider” as our CSP.

openssl pkcs12 -export -in RCA.cert -inkey RCA.key -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out RCA.p12

– To check if the CSP is correct, we can take a look at the .p12 (or .pfx) cert file with this command

openssl pkcs12 -info -nodes -in RCA.p12
Bag Attributes
    localKeyID: 2C 95 10 58 EB B4 96 14 8E CC FE EE 3D 5F 4A 07 42 22 BA 2C 
subject=/C=DE/ST=BY/L=Munich/O=Rongchaua/OU=Home/CN=RongchauaHome
issuer=/C=VN/ST=SG/L=SaiGon/O=SuperVerisign/OU=RootCA/CN=SuperVerisignRootCA
-----BEGIN CERTIFICATE-----
MIICTzCCAbgCCQDU1uCCcOQy6DANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJW
TjELMAkGA1UECAwCU0cxDzANBgNVBAcMBlNhaUdvbjEWMBQGA1UECgwNU3VwZXJW
ZXJpc2lnbjEPMA0GA1UECwwGUm9vdENBMRwwGgYDVQQDDBNTdXBlclZlcmlzaWdu
Um9vdENBMB4XDTExMDcyNTA5MjMxNloXDTEyMDcyNDA5MjMxNlowZjELMAkGA1UE
BhMCREUxCzAJBgNVBAgMAkJZMQ8wDQYDVQQHDAZNdW5pY2gxEjAQBgNVBAoMCVJv
bmdjaGF1YTENMAsGA1UECwwESG9tZTEWMBQGA1UEAwwNUm9uZ2NoYXVhSG9tZTCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3ZNRdsmb9G6toV12tngK1oO4jlMF
8KA5GPqbrRv8ewoOarChiElqoM44/VoIak3qJHTZhElD06gA1OLDxMd144WmskLZ
inOKBIzIKwp56am0QtFJ0zl3yl9TTkcMaw5BLRPSXTrx0QyNgm24bKdm+1OYN5xU
wJw7XCPb5P4Nz58CAwEAATANBgkqhkiG9w0BAQsFAAOBgQDJtSDoj67mO9yCT2/D
zpZtk1IhwNrllnXw6XHSQXYAuuig01tpVjVSPd10MwtZS9t6kUgyMPSrEBn8eVXS
v6nR7Mte6qk4pLCk8Uss0Z+SoEtmMFLGVTlcP3ey13qoI8gdjeakcrZ7V3XaDCYZ
HKckYO/Pf8faC+zht2ZqzTL7BA==
-----END CERTIFICATE-----
Bag Attributes
    localKeyID: 2C 95 10 58 EB B4 96 14 8E CC FE EE 3D 5F 4A 07 42 22 BA 2C 
    Microsoft CSP Name: Microsoft Enhanced RSA and AES Cryptographic Provider
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN2TUXbJm/RuraFd
drZ4CtaDuI5TBfCgORj6m60b/HsKDmqwoYhJaqDOOP1aCGpN6iR02YRJQ9OoANTi
w8THdeOFprJC2YpzigSMyCsKeemptELRSdM5d8pfU05HDGsOQS0T0l068dEMjYJt
uGynZvtTmDecVMCcO1wj2+T+Dc+fAgMBAAECgYBsWTB5xMZlNYXkJV76hSLPmOOz
fPenncGt7EYZ1ViWFenM1Ah5K2Vfstf9U3xP9z+qihUfcfAf3MRjVWvjmqGTMl2v
fFwb9uN+4xTpFuSQ2B/qsj5UZtcO7EkoZn9O/nn1yuqnc0VhsMgAJap+4jT3cHZD
VOQms4vPES5mSqsCmQJBAPdFFn5MF9mOQP/4NZXdchODaQz10VgkYqdbvZXacDZh
Ka62jsJ2GLbhUXdVSykHFs/dQiQ+7wqL8ikNxHu6d8MCQQDlZf7GJTrqUVoZrdbt
CX48QsUPXqaKfVp6tFKN35nV4NudR07FUuJkPuV3ztklc0yIzBholYnODnQXynbv
AOb1AkA01Evz++n0j1IP3kYEmOVwidj97d8mR8/UFeOxipQC6ktvio2Bup2ZJRa0
ukJup5cWHh2thMypojDA2LIsBTDlAkAysrv/5rKCnsAe9MCPWo2/m7IZl32PFe0t
OTUVjdld33gp5lyOV6cZKJ1mQRzUngrIIPM0CfiOxbr6lxB5+eURAkEAuBNP9IS2
ysjwpcAyDqKXHh+MmD39KGZfwxyzsf9lv8WmsRNFmSSwtU/XXPUy2OkpuTvguD3s
+0+h3x9uowQ52A==
-----END PRIVATE KEY-----

So summing up to use our certificate for signing/verifying with SHA256, our certificate must support SHA256 signature algorithm and the CSP must be explicitly declared as “Microsoft Enhanced RSA and AES Cryptographic Provider” if you are using Microsoft CSP. The complete source code and script can be downloaded at “Signing data with SHA256 from certificate

5 thoughts on “C# – How to fix “Invalid algorithm specified” when signing with SHA256”

  1. I found RSA in NAP Client Configuration so my PC is supporting the same.Now is there any changes in program to fix “Invalid algorithm specified”…
    My command prompt showing below error while executing above command
    openssl pkcs12 -info -nodes -in RCA.p12
    as
    ‘open’ is not recognized command

  2. I had a similar problem but the CSPs existed like stated in the post.

    Solution was to delete the following key from registry:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.2.840.113549.1.1.11!4

  3. Hi,

    What is exact relation between Signature Algorithm (i.e sha256WithRSAEncryption) and SHA256 support? I mean Signature Algorithm is defined as an “algorithm used to create the signature of a certificate.” So it does not look like this parameter has anything to do with creating new signature using given certificate. Thanks and regards.

Leave a Reply

Your email address will not be published. Required fields are marked *