Windows Certes how to generate public and private keys

Hello, I would like to ask you for a help.
I am using next VB.NET code for PFX saving, which is good for IIS.

Dim privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256)
Dim cert As CertificateChain = Await myOrder.Generate(New CsrInfo With {.CommonName = dr,
                                            .CountryName = "CZ",
                                            .State = "Czech",
                                            .Locality = "",
                                            .Organization = "",
                                            .OrganizationUnit = "CA"}, privateKey)

Dim pfxBuilder = cert.ToPfx(privateKey)
Dim pfxData = pfxBuilder.Build(dr, My.Settings.pfxPassword)
Dim pfxFileName = Path.Combine(My.Settings.pfxFolder, dr & ".pfx")
File.WriteAllBytes(pfxFileName, pfxData)

I need to have separate private and public keys for streaming software Universal Media Server.
Would you be so kind to point me for some resources how to export these files?

Thank you very much
Miroslav

I don't think you will find many VB.NET developers here. Your question might be better served at https://stackoverflow.com/

4 Likes

Hello, VB.NET is not mandatory. Any .NET language advice is welcome.

I don't think that would make any difference. This Community is mainly for non-coding related Let's Encrypt stuff. Often usage of existing ACME clients is discussed, but usually not the intricate development of said clients.

You might get lucky, but my advice would be to also ask for help somewhere else as Ryan has suggested.

4 Likes

Thank you both for advice.
Miroslav

2 Likes

I would use OpenSSL for Windows from here Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions and then create a VB script to use OpenSSL.

1 Like

Hello, I got same idea and spent half day with this task.
It seems I can export certificate and private key with password, but when I try to remove password, I got error:

C:\mmsw\CertStore>"C:\Program Files\OpenSSL-Win64\bin\openssl" pkcs12 -in pfx\admin.mmsw.cz.pfx -out admin.mmsw.cz.key -nocerts -nodes
Enter Import Password:
C:\mmsw\CertStore>"C:\Program Files\OpenSSL-Win64\bin\openssl" rsa -in admin.mmsw.cz.key -out admin.mmsw.cz1.key
120900:error:0607907F:digital envelope routines:EVP_PKEY_get0_RSA:expecting an rsa key:crypto\evp\p_lib.c:469:
```|

I believe this

is your certificate (+ certificate chain) = public key.

this is your private key.

So you "only" need to save these variables into distinct files to have them separately. Commonly used file formats are PEM (.pem, .crt) or DER (.der, .cer, .crt). How you do that, I have no idea.

Otherwise, you could also use the PFX and back-convert that to its original format - as you have already tried with OpenSSL.

Getting certificates out of PFX files with OpenSSL standalone is pretty ugly. It requires a few tweaks to get it correct:

#!/bin/sh

# 1. Export certificates (leaf + chain) from PFX (but not the private key)
openssl pkcs12 -in file.pfx -password pass:mypassword -nokeys -out certificates.pem

# 2. "certificiates.pem" contains additional PFX-leftover data, which might confuse applications. Remove it.
# Syntax here assumes a unix-like shell
while openssl x509; do :; done < certificates.pem >> certificates_sanitized.pem

# 3. Extract the private key from the PFX
openssl pkcs12 -in file.pfx -password pass:mypassword -nodes -nocerts -out private_key.pem

# 4. The private key also needs to be sanitized
# If our key type is RSA, we can do:
openssl rsa -in private_key.pem -out private_key_sanitized.pem
# If we work with ECDSA keys, we can do:
openssl ec -in private_key.pem -out private_key_sanitized.pem

If your PFX file is encrypted (it appears to be), you must supply a password to OpenSSL. You can pass a password in the command line like this, if that's what you want:

-password pass:mypassword (the pass: in front of your actual password is required)

If you don't want to have your PFX encrypted at all, you must fix the code that sets it:

3 Likes

In certes you can also call .ToPem() on your key and your certificate chain objects, this will give you a PEM encoded version and without a private key password (C# example taken from Certify The Web, where storePath is your output directory) .

    var privateKeyPath = Path.GetFullPath(Path.Combine(new string[] { storePath, "privkey.pem" }));

    System.IO.File.WriteAllText(privateKeyPath, privateKey.ToPem());

    // fullchain.pem - full chain without key
    var fullchainPath = Path.GetFullPath(Path.Combine(new string[] { storePath, "fullchain.pem" }));

    System.IO.File.WriteAllText(fullchainPath, certificateChain.ToPem());
5 Likes

Regarding the OpenSSL error, you created your private key as ES256 (which is an ECDSA key, not RSA). There are RSA options as well.

4 Likes

Hello, thank you very much for your help.
I am still unable to manage point 2. How can I do this in windows cmd?

1 Like

Hello, tank you very much for your help.
I tried these combinations:

privateKey.ToPem()
cert.Certificate.ToPem()

privateKey.ToPem()
cert.ToPem()

Nothing worked.

I had working code in previous version of ACME:

Dim certX509 = New Security.Cryptography.X509Certificates.X509Certificate2(cert.Raw)
Dim crtFileName = Path.Combine(My.Settings.pemFolder, dr.Hostname & ".crt")
Using f = File.CreateText(crtFileName)
          f.WriteLine("-----BEGIN CERTIFICATE-----")
          f.WriteLine(Convert.ToBase64String(certX509.GetRawCertData(), Base64FormattingOptions.InsertLineBreaks))
          f.WriteLine("-----END CERTIFICATE-----")
End Using

Now it has problem with cert.Raw

I don't know of any way to do this with Windows CMD. There are a few alternatives posted here, but none of these work with Windows onboard tools.

You might have to script something yourself. The general idea is to remove the PKCS12 Bag attributes, which are always appended before the -----BEGIN CERTIFICATE----- lines. Note that there will be multiple certificates, each prepended with the bag attributes.

3 Likes

Hello, thank you all for excelent help.
Finally I found solution based on webprofusion advice.
Letsencrypt default certificate type is EC.
I changed it to RSA an suddenly UMedia Server was able to work with it.

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.