Generate a CSR (Certificate Signing Request)
Run a small API that generates a CSR from request parameters.
Full source
<#
Run a small API that generates a CSR (certificate signing request).
POST /certs/csr with JSON body providing subject and key parameters.
FileName: 6.2-Cert-CSR.ps1
#>
param(
[int]$Port = 5000,
[IPAddress]$IPAddress = [IPAddress]::Loopback
)
Initialize-KrRoot -Path $PSScriptRoot
# Configure default logging
New-KrLogger |
Set-KrLoggerLevel -Value Debug |
Add-KrSinkConsole |
Register-KrLogger -Name 'myLogger' -SetAsDefault
New-KrServer -Name "CSR API"
Add-KrEndpoint -Port $Port -IPAddress $IPAddress
Enable-KrConfiguration
# POST /certs/csr
# Body JSON example:
# {
# "DnsNames": ["example.com", "www.example.com"],
# "KeyType": "Ecdsa", # or "Rsa"
# "KeyLength": 384, # 2048 for RSA; 256/384/521 for ECDSA
# "Country": "US",
# "Org": "Acme Ltd.",
# "CommonName": "example.com"
# }
Add-KrMapRoute -Verbs Post -Pattern "/certs/csr" -ScriptBlock {
$body = Get-KrRequestBody
$dns = @()
if ($body.DnsNames) {
if ($body.DnsNames -is [System.Array]) { $dns = $body.DnsNames } else { $dns = @($body.DnsNames) }
}
$params = @{}
if ($dns.Count -gt 0) { $params.DnsNames = $dns }
if ($body.KeyType) { $params.KeyType = [string]$body.KeyType }
if ($body.KeyLength) { $params.KeyLength = [int]$body.KeyLength }
if ($body.Country) { $params.Country = [string]$body.Country }
if ($body.Org) { $params.Org = [string]$body.Org }
if ($body.CommonName) { $params.CommonName = [string]$body.CommonName }
try {
Write-KrLog -Level Debug -Message "Creating CSR with params: {params}" -Values $params
$csr = New-KrCertificateRequest @params
Write-KrLog -Level Debug -Message "CSR created successfully: {csr}" -Values $csr
Write-KrJsonResponse -StatusCode 200 -InputObject @{ csrPem = $csr.CsrPem; privateKeyPem = $csr.PrivateKeyPem ; publicKeyPem = $csr.PublicKeyPem }
} catch {
Write-KrJsonResponse -StatusCode 400 -InputObject @{ error = $_.Exception.Message }
}
}
Start-KrServer
# Clean up and close all the loggers when the server stops
Close-KrLogger
Step-by-step
- Initialize root:
Initialize-KrRoot -Path $PSScriptRootto make relative paths predictable. - Logging: create and register a default console logger at Debug to trace inputs/outputs.
- Server:
New-KrServer -Name 'CSR API'creates a host instance. - Listener: bind to
127.0.0.1:5000withAdd-KrEndpoint -Port 5000 -IPAddress Loopback. - Enable configuration: commit staged changes with
Enable-KrConfiguration. - Apply config:
Enable-KrConfigurationcommits staged settings. - Map route:
Add-KrMapRoute -Verbs Post -Pattern '/certs/csr'handles CSR requests. - Parse input (JSON body):
DnsNames: string or array of strings. Normalized to an array.KeyType:RsaorEcdsa(string; case-insensitive recommended).KeyLength: integer. Common: 2048 for RSA; 256/384/521 for ECDSA.Country,Org,CommonName: optional subject fields.
- Generate CSR: call New-KrCertificateRequest with the assembled parameters. Debug logs capture the request and result objects.
- Respond JSON with:
csrPem: PEM-encoded CSRprivateKeyPem: PEM-encoded private key for the CSRpublicKeyPem: PEM-encoded public key derived from the request
- Errors: on validation or parameter errors, return HTTP 400 with
{ error: <message> }. - Start server:
Start-KrServerbegins processing requests.
Try it
Save the sample locally so it’s easy to run. Copy the contents of pwsh/tutorial/examples/6.2-Cert-CSR.ps1 into a new file in an empty working folder (for example, cert-csr.ps1), then run:
# From your working folder
pwsh .\cert-csr.ps1
curl -X POST http://127.0.0.1:5000/certs/csr -H "Content-Type: application/json" `
-d '{"DnsNames":["example.com"],"KeyType":"Ecdsa","KeyLength":384,"Country":"US","Org":"Acme Ltd.","CommonName":"example.com"}'
Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:5000/certs/csr' -ContentType 'application/json' -Body (@{
DnsNames = @('example.com'); KeyType = 'Ecdsa'; KeyLength = 384; Country = 'US'; Org = 'Acme Ltd.'; CommonName = 'example.com'
} | ConvertTo-Json)
# (Optional) Save returned PEMs
# $resp = Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:5000/certs/csr' -ContentType 'application/json' -Body (@{
# DnsNames = @('example.com'); KeyType = 'Ecdsa'; KeyLength = 384; Country = 'US'; Org = 'Acme Ltd.'; CommonName = 'example.com'
# } | ConvertTo-Json)
# $resp.csrPem | Set-Content -Path './example-com.csr' -NoNewline
# $resp.privateKeyPem | Set-Content -Path './example-com.key' -NoNewline
# $resp.publicKeyPem | Set-Content -Path './example-com.pub' -NoNewline
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 400 Bad Request | Missing/invalid input fields | Provide required fields; check KeyType/KeyLength validity |
| Wrong key algorithm | Case mismatch in KeyType | Use Rsa or Ecdsa (case-insensitive recommended) |
| Empty PEM fields | CSR generation failed | Inspect logs; ensure parameters map to New-KrCertificateRequest |
| Server not reachable | Port blocked/in use | Use loopback 127.0.0.1:5000 and verify nothing else uses the port |
References
Previous / Next
Go back to Self‑Signed or continue to Import / Export / Validate.