Kenc.ACMELib

Free and open source software ACME protocol v2 implementation in C# .NET Core, allowing cross-platform automated interaction with certificate authorities like Let's Encrypt.

C# .NET SSL Security

About the Project

Kenc.ACMELib provides a simple and reliable way to automate SSL certificate issuance and renewal using the ACME protocol. It's designed to be easy to integrate into any .NET application while providing full control over the certificate management process.

Key Features

  • Full implementation of ACME protocol v2
  • Support for Let's Encrypt and other ACME-compatible CAs
  • Cross-platform compatibility (.NET Standard 2.1)
  • Supports both HTTP and DNS validation challenges
  • Thread-safe operations for concurrent certificate requests
  • Comprehensive error handling and logging

Code Examples

For more code samples, checkout the /examples/ folder in the source repository.

Basic Usage

var acmeClient = new ACMEClient(ACMEEnvironment.StagingV2, rsaKey, new RestClientFactory());
ACMEDirectory directory = await acmeClient.InitializeAsync();
var account = await acmeClient.RegisterAsync(new[] { "mailto:" + userContact });
Order result = await acmeClient.OrderAsync(new[] {"domain.test","*.domain.test"});

Complete Certificate Request

// Create client and initialize
var acmeClient = new ACMEClient(ACMEEnvironment.StagingV2, rsaKey, new RestClientFactory());
await acmeClient.InitializeAsync();
// Register account
var account = await acmeClient.RegisterAsync(new[] { "mailto:admin@example.com" });
// Create order for certificates
var order = await acmeClient.OrderAsync(new[] { "example.com", "www.example.com" });
// Get authorizations that need to be completed
var authorizations = await acmeClient.GetAuthorizationsAsync(account, order);
// Complete each authorization (HTTP challenge shown here)
foreach (var auth in authorizations)
{
var challenge = auth.Challenges.First(c => c.Type == "http-01");
var keyAuth = acmeClient.GetKeyAuthorization(account, challenge.Token);
// Implement method to make this value available at:
// http://example.com/.well-known/acme-challenge/{challenge.Token}
SetupHttpChallenge(challenge.Token, keyAuth);
// Notify ACME server to validate the challenge
await acmeClient.CompleteChallenge(account, challenge);
}
// Generate CSR and complete the order
var privateKey = GenerateRsaPrivateKey();
var csr = GenerateCsr(privateKey, new[] { "example.com", "www.example.com" });
await acmeClient.FinalizeOrderAsync(account, order, csr);
// Download the certificate
var certificate = await acmeClient.GetCertificateAsync(account, order);

Blog posts tagged with Acmelib

Migrating Kenc.ACMELib to Semantic Versioning

Back when I made the first publically available build of Kenc.ACMELib I wanted to go for semantic versioning, but with the default format in Azure DevOps being $(date:yyyy).$(date:MM).$(date:dd)$(rev:.r), the first…