I'm lost in a twisty maze of certificates and private keys.
I am writing a server in C#. I want it to accept SSL connections. For test purposes, I want to generate a certificate for "localhost", and use that certificate for the server. Ideally I don't want to pollute my certificate store, so I just want a file, or files, on disk that the C# code can load to provide the certificate.
Everything I have tried (using cookbook approaches suggested by web searches) either gives me "The credentials supplied to the package were not recognized" or "The server mode SSL must use a certificate with the associated private key."
Is there a way to generate a certificate and private key, and subsequently to load them into an X509Certificate object without also loading them into my machine certificate store?
Niki Loche method works.
If you get The specified network password is not correct.
, then you should try it without password in C#. It doesn't matter what your input password was in makecert
.
certificate = new X509Certificate2("Server.pfx", "");
But if you want to use password (there is a reason, it's there :)), try changing pvk2pfx.exe command to:
pvk2pfx.exe" -pi password -pvk Server.pvk -spc Server.cer -pfx Server.pfx
and in C# enter:
certificate = new X509Certificate2("Server.pfx", "password");
Password must be the same as it is in creating cer file.
That did the trick for me. I hope it will help someone.
I recently developed a SMTP server with TLS. I needed to install the server as a Windows Service on a Windows Server 2012 box. I used a Let's Encrypt SSL Certificate (* wildcard) for my domain. While developing "on the server" I had to run Visual Studio as Administrator for my code to work using "new X509Certificate("cert.pfx", "{password}") and it ran perfectly. However, once installed as a service, that scheme did not work. Turns out the simpler/safer way is to use X509Store. Here's the code that solved the problem...
private X509Certificate GetSslCertificate()
{
X509Certificate cert = null;
string certname = "*.mydomain.com";
try
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly);
foreach (X509Certificate certificate in store.Certificates)
{
if (certificate.Subject.ToLower().Contains(certname))
{
cert = certificate;
break;
}
}
}
catch (Exception) { /* Handle Exception */ }
return cert;
}
Also notice I used "LocalMachine" as the StoreLocation. You'll need to change to CurrentUser if that's where you installed your SSL Certificate.
In the end, I ran the following to create a server.pfx file:
makecert.exe -r -pe -n "CN=localhost" -sky exchange -sv server.pvk server.cer
pvk2pfx -pvk server.pvk -spc server.cer -pfx server.pfx
Then I loaded it in code with:
certificate = new X509Certificate2("server.pfx", "password");
(I didn't actually hard code the password like that :-)
The trick was to know that I needed a pfx file, and that I needed to load it using the X509Certificate2 class, rather than X509Certificate.
There are a number of tools that should let you act as your own CA and generate a certificate. XCA is one of them. There are also a number of methods using OpenSSL commands, for example.
Generating a self-signed certificate only may seem like the easiest option, but using a test CA (and a separate server certificate) may be worth it. This would allow you to import the test CA into the browser's store if needed to make the tests more realistic. It's not much more difficult with the right tools (e.g. XCA).
Once you have generated your server certificate and its private key, turn it into a PKCS#12 file (.p12/.pfx).
You should then be able to load it using X509Certificate2.import(...)
. (See example in this answer.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With