Quantcast
Channel: Common Language Runtime Internals and Architecture forum
Viewing all articles
Browse latest Browse all 1710

Programmaticaly create a self-signed certificate with SHA256 and not SHA1

$
0
0

I need to create a self signed certificate in code. I have a working example using Security.Cryptography.dll from http://clrsecurity.codeplex.com but it uses SHA1 and I need to use SHA256.

I've updated the provided example to use SHA256 algorithm but I don't know how to force it to use "Microsoft Enhanced RSA and AES Cryptographic Provider" as CSP.

When accessing the privateKey of the generated certificate I get a System.Security.Cryptography.CryptographicException "Invalid provider type specified."

   at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
   at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
   at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()


I've read a lot of posts on this subject without finding a way to do this. I've also tried calling the Native API Crypt32.dll, CertCreateSelfSignCertificate but it only gives me SHA1 and when I try to pass in the following parameters:

_In_opt_ PCRYPT_KEY_PROV_INFO            pKeyProvInfo,

_In_opt_ PCRYPT_ALGORITHM_IDENTIFIER     pSignatureAlgorithm

It fails with an exception - probably because the structure I created isn't correct but I'm finding the documentation a bit limited.

So that is why my current approach is with Security.Cryptography.dll as it seems easier but I can't figure out how to force it to use the provider it needs for SHA256.

Below is the code:

private void CreateCertificate(string fileName, string password)
	{
		X509Certificate2 cert = null;
		var name = new X500DistinguishedName("cn=" + WindowsIdentity.GetCurrent().Name);
		// Generate Key
		CngKeyCreationParameters keyParams = new CngKeyCreationParameters();
		keyParams.KeyUsage = CngKeyUsages.Signing;
		keyParams.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider;
		//keyParams.Provider = new CngProvider("Microsoft Enhanced RSA and AES Cryptographic Provider");
		keyParams.ExportPolicy = CngExportPolicies.AllowExport;
		keyParams.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None));

		CngKey newKey = CngKey.Create(CngAlgorithm2.Rsa, Guid.NewGuid().ToString(), keyParams);

		// Init certificate
		X509CertificateCreationParameters certParams = new X509CertificateCreationParameters(name);
		certParams.StartTime = DateTime.Today.AddDays(-1);
		certParams.EndTime = DateTime.Today.AddYears(30);
		certParams.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha256;
		// Create cert
		cert = newKey.CreateSelfSignedCertificate(certParams);

		using (Stream outputStream = File.Create(fileName))
		{
			byte[] pfx = cert.Export(X509ContentType.Pfx, password);
			outputStream.Write(pfx, 0, pfx.Length);
			outputStream.Close();
		}
	}

Please note that I can't use makecert, openssl or powershell since I need to do it in c# only.



Karin, Stockholm


Viewing all articles
Browse latest Browse all 1710

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>