Scenario 2.3: Create Multi-SAN CSR

Category: Certificate Signing Requests (CSR)
Complexity: * (Medium-High)
Prerequisites: Key pair available
Estimated Time: 10-15 minutes </WRAP> —- ===== Description ===== This scenario describes creating a CSR with multiple Subject Alternative Names (SANs). This is necessary for certificates that need to secure multiple domains, subdomains, or IP addresses. Use cases: * Multi-domain certificates (SAN certificates) * Wildcard + explicit domains combined * Internal + external names * Load balancer with multiple backends —- ===== SAN Types ===== ^ Type ^ GeneralName Tag ^ Example ^ Usage ^ | DNS | dNSName (2) | www.example.com | Websites, APIs | | IP | iPAddress (7) | 192.168.1.100 | Internal services | | Email | rfc822Name (1) | admin@example.com | S/MIME | | URI | uniformResourceIdentifier (6) | https://example.com | SAML, OIDC | | UPN | otherName (0) | user@domain.local | Windows Auth | —- ===== Code Example (C#) ===== <code csharp> using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using var ctx = PqCryptoContext.Initialize(); using var key = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); var dn = new DnBuilder() .AddCN(„example.com“) Primary domain .AddO(„Example GmbH“) .AddC(„DE“) .Build(); Multi-SAN with different types var extensions = new ExtBuilder() .SubjectAlternativeName(new[] { DNS names „dns:example.com“, „dns:www.example.com“, „dns:api.example.com“, „dns:app.example.com“, „dns:*.dev.example.com“, Wildcard for dev IP addresses (for internal access) „ip:10.0.0.100“, „ip:192.168.1.50“, IPv6 „ip:2001:db8::1“ }) .KeyUsage(KeyUsageFlags.DigitalSignature | KeyUsageFlags.KeyEncipherment) .ExtendedKeyUsage(ExtKeyUsage.ServerAuth) .Build(); var csr = ctx.CreateCertificateRequest(key, dn, extensions); Output all SANs Console.WriteLine(„Subject Alternative Names:“); foreach (var san in csr.SubjectAlternativeNames) { Console.WriteLine($„ - {san}“); } File.WriteAllText(„multi-san.csr.pem“, csr.ToPem()); </code> —- ===== Combining Wildcard + Explicit ===== <code csharp> var extensions = new ExtBuilder() .SubjectAlternativeName(new[] { „dns:example.com“, Root domain (wildcard does not cover this!) „dns:*.example.com“, All 1st level subdomains „dns:*.api.example.com“, API subdomains „dns:legacy.old-domain.com“ Alternative domain }) .Build(); </code>

Important: Wildcards (*.example.com) only cover one level and not the root domain itself! Therefore always specify both example.com AND *.example.com.

—- ===== Kubernetes / Cloud-Native ===== <code csharp> var extensions = new ExtBuilder() .SubjectAlternativeName(new[] { Kubernetes Service DNS „dns:my-service“, „dns:my-service.default“, „dns:my-service.default.svc“, „dns:my-service.default.svc.cluster.local“, Headless Service (Pod DNS) „dns:*.my-service.default.svc.cluster.local“, External Ingress Domain „dns:api.example.com“ }) .Build(); </code> —- ===== Limits and Best Practices ===== ^ Aspect ^ Recommendation ^ Reason ^ | Number of SANs | Max. 100 | Performance, certificate size | | Wildcard levels | Only 1 level | RFC 6125 restriction | | IP addresses | Only when necessary | IPs change more frequently | | Internal names | Separate certificates | Security separation | —- ===== Related Scenarios ===== ^ Relationship ^ Scenario ^ Description ^ | Next Step | 3.1 Server Certificate | Sign CSR | | Alternative | 3.5 Wildcard Certificate | Wildcard only | | Foundation** | 2.1 Server CSR | Simple server CSR |


« <- 2.2 Client CSR | ^ CSR Overview | 2.4 Process CSR -> »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional