View Categories

Configuring the SSL certificate

The ODDC Server uses a secure HTTPS connection, which requires a trusted server certificate.*

You can use an existing certificate. You must specify the certificate’s thumbprint in the ar.oddc.server.config.json file, under the “CertificateThumbprint” section:

"CertificateThumbprint": "yourTHUMBPRINThere"

Ensure that the technical user has read access to the certificate.

*If you do not have a certificate for setup, create a self-signed certificate for internal use; the user must have read access to it. See the script below (Windows Server 2025).

Create self-signed certificate (Powershell script)

#Requires -RunAsAdministrator
 
$ErrorActionPreference = "Stop"
 
# Get the server names
$serverName      = $env:COMPUTERNAME
$serverNameLocal = "$serverName.local"
 
# Local Windows account that needs access to the private key
$userName = "$serverNameoddc_techuser"
 
# Verify that the user account exists
try {
    $account = New-Object System.Security.Principal.NTAccount($userName)
 
    $null = $account.Translate(
        [System.Security.Principal.SecurityIdentifier]
    )
}
catch {
    throw "The Windows account '$userName' does not exist or cannot be resolved."
}
 
# 1. Create the self-signed certificate in LocalMachineMy
$cert = New-SelfSignedCertificate `
    -DnsName $serverName, $serverNameLocal, "localhost" `
    -CertStoreLocation "Cert:LocalMachineMy" `
    -FriendlyName "ODDC Server 5.1 self-signed certificate" `
    -KeyAlgorithm RSA `
    -KeyLength 2048 `
    -KeyUsage DigitalSignature, KeyEncipherment `
    -TextExtension @(
        "2.5.29.37={text}1.3.6.1.5.5.7.3.1"
    ) `
    -NotAfter (Get-Date).AddYears(1)
 
Write-Host "Certificate created in LocalMachineMy."
 
# 2. Add the certificate to LocalMachineRoot
$tempCertPath = Join-Path $env:TEMP "$serverName-$($cert.Thumbprint).cer"
 
try {
    Export-Certificate `
        -Cert $cert `
        -FilePath $tempCertPath `
        -Force | Out-Null
 
    Import-Certificate `
        -FilePath $tempCertPath `
        -CertStoreLocation "Cert:LocalMachineRoot" | Out-Null
 
    Write-Host "Certificate added to LocalMachineRoot."
}
finally {
    if (Test-Path $tempCertPath) {
        Remove-Item -Path $tempCertPath -Force
    }
}
 
# 3. Locate the certificate's private key
$certPath = "Cert:LocalMachineMy$($cert.Thumbprint)"
$cert     = Get-Item -Path $certPath
 
if (-not $cert.HasPrivateKey) {
    throw "The certificate does not have a private key."
}
 
$rsa = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey(
    $cert
)
 
if ($null -eq $rsa) {
    throw "The RSA private key could not be opened."
}
 
try {
    if ($rsa -is [System.Security.Cryptography.RSACng]) {
 
        # CNG private keys are stored in:
        # C:ProgramDataMicrosoftCryptoKeys
        $keyFilePath = Join-Path `
            "$env:ProgramDataMicrosoftCryptoKeys" `
            $rsa.Key.UniqueName
 
        $providerType = "CNG"
    }
    elseif ($rsa -is [System.Security.Cryptography.RSACryptoServiceProvider]) {
 
        # Legacy CSP private keys are stored in:
        # C:ProgramDataMicrosoftCryptoRSAMachineKeys
        $keyFilePath = Join-Path `
            "$env:ProgramDataMicrosoftCryptoRSAMachineKeys" `
            $rsa.CspKeyContainerInfo.UniqueKeyContainerName
 
        $providerType = "CSP"
    }
    else {
        throw "Unsupported RSA provider: $($rsa.GetType().FullName)"
    }
 
    if (-not (Test-Path -LiteralPath $keyFilePath)) {
        throw "The private key file was not found: $keyFilePath"
    }
 
    # 4. Grant Read permission to oddc_techuser
    $acl = Get-Acl -LiteralPath $keyFilePath
 
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
        $userName,
        [System.Security.AccessControl.FileSystemRights]::Read,
        [System.Security.AccessControl.AccessControlType]::Allow
    )
 
    $acl.AddAccessRule($accessRule) | Out-Null
 
    Set-Acl `
        -LiteralPath $keyFilePath `
        -AclObject $acl
 
    # 5. Verify the resulting permission
    $permission = (Get-Acl -LiteralPath $keyFilePath).Access |
        Where-Object {
            $_.IdentityReference.Value -eq $userName -and
            $_.AccessControlType -eq "Allow" -and
            ($_.FileSystemRights -band
                [System.Security.AccessControl.FileSystemRights]::Read)
        }
 
    if (-not $permission) {
        throw "The private key permission could not be verified."
    }
 
    Write-Host ""
    Write-Host "Private key permission successfully added."
    Write-Host "Account:      $userName"
    Write-Host "Permission:   Read"
    Write-Host "Provider:     $providerType"
    Write-Host "Private key:  $keyFilePath"
}
finally {
    if ($null -ne $rsa) {
        $rsa.Dispose()
    }
}
 
Write-Host ""
Write-Host "Certificate configuration completed successfully."
Write-Host "Thumbprint: $($cert.Thumbprint)"
Write-Host "DNS names:  $serverName, $serverNameLocal, localhost"