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

Development

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 few builds ended up using that format and I kinda stuck with it.

Introducing Kenc.ACMELib (Lets Encrypt client in .net)

Development

About a year ago I started using Lets Encrypt for my certificate needs for a variety of websites and online services I run, but being mostly Windows based, I lacked a great automation solution. In the beginning I tried various solutions, including solutions for automatic certificate renewal for A