How to create a certificate to use with SslStream AuthenticateAsServer without importing

10,141

Solution 1

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.

Solution 2

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.

Solution 3

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.)

Solution 4

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.

Share:
10,141

Related videos on Youtube

Nikki Locke
Author by

Nikki Locke

I am a consultant/programmer working for my own company, currently mostly programming in C#, but with extensive experience in C++, SQL, C, Java, Basic, PHP and even 8086 Assembler (although I have forgotten most of that!). I also maintain the "Available C++ Libraries" FAQ, listing over 400 libraries for use with C++ (see my web page).

Updated on June 29, 2022

Comments

  • Nikki Locke
    Nikki Locke almost 2 years

    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?

  • ssss
    ssss about 11 years
    Does not work. I get a CryptographicException saying “The specified network password is not correct.”, which is patently false because I used the password x, which is very hard to mistype. Any ideas for a fix?
  • Jean-Bernard Pellerin
    Jean-Bernard Pellerin about 9 years
    To others that can't get this to work, see: stackoverflow.com/a/19719140/103959