Webprofusion.Certes

A client implementation for the Automated Certificate Management Environment (ACME) protocol. This package is a fork of the excellent https://github.com/fszlin/certes project with updated packaging and feature updates. Used by https://certifytheweb.com


Keywords
Certes, letsencrypt, ACME, HTTPS, SSL, Certificate, dotnettool, dotnet
License
MIT
Install
Install-Package Webprofusion.Certes -Version 2.3.7

Documentation

Anvil

The project is a fork of https://github.com/fszlin/certes with packaging updates, feature updates and experimental extensions.

This library is an ACME client implementation primarily used by https://certifytheweb.com and is subject to changes required by that application.

Extended Features:

  • ACME ARI (renewal info)
  • Certificate chain build does not require installed/embedded root cert
  • Optional use of modern PFX cert/key algorithms for OpenSSL 3.x+ compatibility
  • Authority token challenges, tkauth-01 and TnAuthList

Account

Creating new ACME account:

var acme = new AcmeContext(WellKnownServers.LetsEncryptStagingV2);
var account = await acme.NewAccount("admin@example.com", true);

// Save the account key for later use
var pemKey = acme.AccountKey.ToPem();

Use an existing ACME account:

// Load the saved account key
var accountKey = KeyFactory.FromPem(pemKey);
var acme = new AcmeContext(WellKnownServers.LetsEncryptStagingV2, accountKey);
var account = await acme.Account();

See API doc for additional operations.

Order

Place a wildcard certificate order (DNS validation is required for wildcard certificates)

var order = await acme.NewOrder(new[] { "*.your.domain.name" });

Generate the value for DNS TXT record

var authz = (await order.Authorizations()).First();
var dnsChallenge = await authz.Dns();
var dnsTxt = acme.AccountKey.DnsTxt(dnsChallenge.Token);

Add a DNS TXT record to _acme-challenge.your.domain.name with dnsTxt value.

For non-wildcard certificate, HTTP challenge is also available

var order = await acme.NewOrder(new[] { "your.domain.name" });

Authorization

Get the token and key authorization string

var authz = (await order.Authorizations()).First();
var httpChallenge = await authz.Http();
var keyAuthz = httpChallenge.KeyAuthz;

Save the key authorization string in a text file, and upload it to http://your.domain.name/.well-known/acme-challenge/<token>

Validate

Ask the ACME server to validate our domain ownership

await challenge.Validate();

Certificate

Download the certificate once validation is done

var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256);
var cert = await order.Generate(new CsrInfo
{
    CommonName = "your.domain.name",
}, privateKey);

Export full chain certification

var certPem = cert.ToPem();

Export PFX

var pfxBuilder = cert.ToPfx(privateKey);
var pfx = pfxBuilder.Build("my-cert", "abcd1234");