AcmeCLI WildCard Certificate Can not be imported to IIS


#1

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:WorldEducation.infi

I ran this command:acmecli --email jane.doe@example.com --email john.doe@email.com --accept-tos --dns *.worldeducation.info --test-challenges --wait-for-test:600 --answer-challenges --wait-for-authz --finalize --key-algor ec --key-size 256 --wait-for-cert --export-cert my-example.pem --export-pfx my-example.pfx

It produced this output: it creates .pfx file and and a .pem file and csr file

My web server is (include version):

The operating system my web server runs on is (include version): windows server 2016

When I try to import the .pfx file to IIS 10 i got error certificate does not have a private key.

to be noted: .pem file size is 4 kb but the .pfx file is 2 kb

i need help to import the certificate to IIS & use it on my domain.

Thanks


#2

Google search for import certificate iis.


#3

Yes I know this process.i have done several time but the import fail with an error “The certificate doe not have a private key”

I have followed EBEKKERS ACMECLI process to generate certificate.

if (ExportPfx != null)
{
Console.WriteLine(“Exporting Certificate as PKCS12…”);

                    using (var cert = new X509Certificate2(LoadRaw<byte[]>(
                           true, Constants.AcmeOrderCertFmt, orderId)))
                    {
                        
                        await File.WriteAllBytesAsync(_statePath + "\\" + t.Host + ".pfx",
    cert.Export(X509ContentType.Pkcs12));
                    }

}
i think the above code is not generating correct .PFX file.


#4

Hi @budheshwarnath

the import is critical. You must import the X509certificate2 with these options:

X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet

into your webhosting certificate store. And you need something like

RSACryptoServiceProvider.UseMachineKeyStore = True

in your code.


#5

Hi @JuergenAuer,
Thanks for your reply. No i am not importing the .pfx file through C# code.
After the .pfx file downloaded, I went to the IIS certificate Store, right click on it & then click to import.
After giving the .pfx file path and password and selecting the WebHosting as store when i click to import it gives me error “The certificate does not have any private key”.

Please suggest me if i can import the downloaded .pfx file in any other way.


#6

Hi @budheshwarnath,

I tried running the ACMECLI project (which appears to be an example program inside the AcmeSharp project) inside a microsoft/dotnet container, using the parameters you passed.

Indeed, the exported PFX does not seem to contain the private key, only the certificate. I verified this by dumping the contents using openssl pkcs12.

So perhaps you can try another program or report this to the authors.


#7

What’s the content of this Load-Operation?

Only the signed file sent from Letsencryt? If yes, this isn’t enough.

This new X509Certificate2 must be matched with the RSA-Object which has the private Key.

Something like

cert.PrivateKey = _RSA_DomainKey

if _RSA_DomainKey is the RSACryptoServiceProvider - object used to create the public/private key pair and the Certificate Signing request.


#8

@_az,
Sorry for late response. Yes you are right,the above code does not export the private key with the .pfx file.

Now I have solved it in another way. I am putting it here if somebody is required.

I have changed the following code in ACMECLI:

case Constants.RsaKeyType:
certKeys = CryptoHelper.Rsa.GenerateKeys(KeySize ?? Constants.DefaultAlgorKeySizeMap[KeyAlgor]);
key = CertHelper.GenerateRsaPrivateKey(2048); // #chan333 add
using (var rsa = CryptoHelper.Rsa.GenerateAlgorithm(certKeys))
{
certCsr = CryptoHelper.Rsa.GenerateCsr(Dns, rsa);
}
break;

TO

case Constants.RsaKeyType:
key = CertHelper.GenerateRsaPrivateKey(2048);
certCsr = CertHelper.GenerateRsaCsr(Dns, key);
break;

then creating a Private key .PEM file

using (var keyPem = new MemoryStream())
{
CertHelper.ExportPrivateKey(key, EncodingFormat.PEM, keyPem);
keyPem.Position = 0L;
Save(AcmeOrderCertKeyFmt, keyPem);
}

and in the final code block of exporting .pfx file:

if (ExportPfx != null)
{
Console.WriteLine(“Exporting Certificate as PKCS12…”);
var certByte = Load<byte>(Constants.AcmeOrderCertFmt).value;
key = CertHelper.ImportPrivateKey(EncodingFormat.PEM,
Load(AcmeOrderCertKeyFmt).value);

using (var crtStream = new MemoryStream(certByte))
using (var pfxStream = new MemoryStream())
{
Console.WriteLine(“Reading in Certificate chain (PEM)”);
var cert = ACMEKestrel.Crypto.CertHelper.ImportCertificate(EncodingFormat.PEM, crtStream);
Console.WriteLine(“Writing out Certificate archive (PKCS12)”);

                        CertHelper.ExportArchive(key, new[] { cert }, ArchiveFormat.PKCS12, pfxStream, "chanchal");
                        pfxStream.Position = 0L;
                        Save(_statePath + "\\" + t.Host + ".pfx", pfxStream);
                    }

}

and then i import to IIS and it is imported and the wild card certificate working fine

Hope this helps someone.

@JuergenAuer
The content is:
-----BEGIN CERTIFICATE-----
MIIFYjCCBEqgAwIBAgISBKPiklDHdHyuQzCEfOcyY6MbMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODEyMDQwODEyNTFaFw0x
OTAzMDQwODEyNTFaMCAxHjAcBgNVBAMMFSoud29ybGRlZHVjYXRpb24uaW5mbzCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKfpaswLYBYHTYX200r6rwpL
Lhd8GLNWWSBzVxGYQSYdiOP5ywsd3mBmVi6pqu3Oi6BJH7bguRfDEpSU9sr3sOKJ
Vb6XMiSwdi5sfBjkg1UuiLIXXLIr2W0oCvwYLeNMXh4UKLu/Sep+8ri22vh6YPix
+egXbj+jPOZkuDK3Kt0O6LycZyOQqYlx9D2i2ZCnkWmrkd+6Uqopk3bHDOPeg7zt
2UtBZKdiTa+QdCO5mMXAT1jnphLkHCzh96IBg0pHqbEV2nvqzRRN4EPpoKdLmuRr
iu4QuNA1gBymgbEbBbr8y6y3xx9RTsTUrhvG0CpMUQtqMWU+r80rZI4jbXrQ1NsC
AwEAAaOCAmowggJmMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUL0+AeVV43j7em5Qg
K4SO9oVeTgEwHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7/Oo7KEwbwYIKwYB
BQUHAQEEYzBhMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcC5pbnQteDMubGT0c2Vu
Y3J5cHQub3JnMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMubGV0c2Vu
Y3J5cHQub3JnLzAgBgNVHREEGTAXghUqLndvcmxkZWR1Y2F0aW9uLmluZm8wTAYD
VR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEXKDAmBggrBgEFBQcCARYa
aHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1BIHy
APAAdwBVgdTCFpA2AUrqC5tXPFPwwOQ4eHAlCBcvo6odBxPTDAAAAWd4fdQ3AAAE
AwBIMEYCIQD3BgSj22D5XajGqD5V3gL6ly/SDMvPBqa5Tp0vorvriAIhAIDW4Yui
5bp0TYZ/+rtumrtFbZZS7lYTYcNJWWGqj/fxAHUAKTxRllTIOWW6qlD8WAfUt2+/
WHopctykwwz05UVH9HgAAAFneH3TTQAABAMARjBEAiBcmSqmpldwHlM0nPDOv20p
r3stVEMRl6h9bHne5BPF5gIgWoo7dUXgAx7WikgBzScvRg9p8EsGn3MaiqwHETLm
aDowDQYJKoZIhvcNAQELBQADggEBAAUz2n6nb2RR/wGJ9IKOBJjeK3CMUoC1P+aU
fHNj+DQWiaDNpjMQrACu5boFKs1VduKdS+qkPeyJ19SOADEto5S1as3PtbBSapA8
nxFI+d0wsQ+kwt8zsQVcrb3H4D9+nJzPCyKabecGkJGHM4FmRPHzu/zQqJBUdv7/
QP+StIweZuqMAUbrJWsQ0P00qTFWmFy/TcBnHf2hiVCk4/JiM6FQF1Acq/PLBbiR
AqorN/fpZYnaV+psyQyfJRsZDPF1kU9xuBASkI7lhXonluHYphQ0qKWuLeIvJ8PS
zdiR8phBY8J5BXN3OwHGHhu6OWpCoUw0zKvywLB9+VnWM8bwqTg=
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3vrvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy80cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVQdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8ddCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----


#9

Thanks.

Yep, this is the content of the two public visible certificates (your own and the intermediate of Letsencrypt). These files never contains the private key of your certificate.

But now you can add the private key via code.


#10

@budheshwarnath sounds like you’ve solved it but acme-cli is a demo for the acmesharpcore library and is not yet a mature acme client, please submit a PR (or at least an issue) for your suggested changes: https://github.com/PKISharp/ACMESharpCore/issues

You can also look at other windows clients which support wildcards such as certes (still a cli but arguably a bit more mature than acme-cli), Posh-ACME or https://certifytheweb.com (my GUI, which currently uses certes internally). Unless of course you love doing this kind of thing yourself, I know a lot of people like to do that :slight_smile: