Creating SSL Certificate with Custom CA

Creating Default OpenSSL Config File
Creating Custom Root CA
Creating the CA key:
openssl genrsa -des3 -out root-CA.key 4096
Note: remove -des option to create key without password
Creating self sign CA certificate
openssl req -x509 -new -nodes -key root-CA.key -sha256 -days 3650 -out root-CA.crt `
    -subj "/C=ID/O=Dev lab/CN=Dev lab Root CA" `
    -addext 'keyUsage = cRLSign, keyCertSign, digitalSignature' `
    -addext 'extendedKeyUsage = critical, serverAuth, clientAuth, codeSigning, emailProtection, timeStamping' `
    -addext 'subjectKeyIdentifier=hash' `
    -addext 'authorityKeyIdentifier=keyid:always,issuer:always' `
    -addext "basicConstraints = critical, CA:TRUE"
Explanations:
  • subj
    create unattended answer subject

  • basicConstraints
    CA:TRUE means it's issuer

  • keyUsage
    determine what's this cert for: certificate signing (keyCertSign), CRL signing (cRLSign), digital signature

  • extendedKeyUsage
    an extended version of keyUsage: server authentication (serverAuth), client authentication (clientAuth), file/code signing (codeSigning), S/MIME signing (emailProtection), time stamping

  • subjectKeyIdentifier
    identifier of this cert

  • authoritykKeyIdentifier

  • the identifier which signs the cert, if it's root cert, then it should be itself
    Shorter version
    openssl req -config openssl.cnf -x509 -new -nodes -key root-CA.key -out root-CA.crt -days 3650 -extensions ca_cert -subj "/C=ID/O=Dev Lab/CN=Dev Lab Root CA"
    Reference: OpenSSL man page
    Inspect root CA certificate
    openssl x509 -noout -text -in root-CA.crt
    Convert into PKCS12 (.pfx) format
    openssl pkcs12 -export -name "Root CA" -out root-CA.pfx -inkey root-CA.key -in root-CA.crt
    Then import the pfx file into local machine placed under Trusted Root Certification Authorities
    Creating Intermediate CA
    Creating the intermedia CA key
    openssl genrsa -out server-CA.key 4096
    Creating intermediate certificate request
    openssl req -new -key server-CA.key -out server-CA.csr -subj "/C=ID/O=Dev Lab/OU=Development/CN=Dev Lab Server CA"
    Sign the intermedia CA certificate's request with CA's key and cert:
    openssl x509 -extfile openssl.cnf -req -in server-CA.csr -CA root-CA.crt -CAkey root-CA.key -CAcreateserial -out server-CA.crt -extensions ica_cert -days 3650
    Inspect root CA certificate
    openssl x509 -noout -text -in server-CA.crt
    Convert into PKCS12 format
    openssl pkcs12 -export -name "Dev lab Server CA" -inkey server-CA.key -in server-CA.crt -out server-CA.pfx
    Then import the pfx file into local machine placed under Intermediate Certification Authorities
    Creating User Certificate
    Creating the certificate key
    openssl genrsa -out dev.lab.key 2048
    Before moving on, the openssl config is configured to accept subject alternate name from environment variable named SAN (see line 176), so you need to configure first, otherwise, it will fail: $Env:SAN = 'DNS:*.dev.lab, DNS:dev.lab'. You can set it to the same as CN if you don't want to assign it to wilcard domain. We can also assign it to IP address as follows: $Env:SAN = 'DNS:*.dev.lab,DNS:dev.lab,DNS:localhost,IP:127.0.0.1'. After that, we can continue to create certificate request
    openssl req -new -key dev.lab.key -out dev.lab.csr -subj "/C=ID/ST=Jakarta/O=Dev Home/OU=Development/CN=*.dev.lab"
    Sign the certificate request using server CA's key and certificate
    openssl x509 -extfile openssl.cnf -extensions web_cert -req -CA server-CA.crt `
        -CAkey server-CA.key -CAcreateserial -days 365 `
        -in dev.lab.csr -out dev.lab.crt
    Convert into PKCS12 format
    openssl pkcs12 -export -name "dev.lab Certificate" -inkey dev.lab.key -in dev.lab.crt -out dev.lab.pfx
    Import the .pfx file into local machine using default location.
    Creating S/MIME Certificate
    Creating the certificate key
    openssl genrsa -out iroel-email.key 2048
    Creating certificate request
    openssl req -new -key iroel-email.key -out iroel-email.csr -subj "/C=ID/ST=Jakarta/CN=Fakhrulhilal Maktum/emailAddress=iroel@dev.lab" -addext "subjectAltName = email:iroel@dev.lab, email:iroel@other.lab"
    Sign the certificate request using server CA's key and certificate
    $Env:SAN = 'email:iroel@dev.lab, email:iroel@dev.test'
    openssl x509 -extfile openssl.cnf -extensions smime_cert -req -CA server-CA.crt `
        -CAkey server-CA.key -CAcreateserial -setalias "Dev email certificate" `
        -in iroel-email.csr -out iroel-email.crt -trustout -days 365
    Convert into PKCS12 format
    openssl pkcs12 -export -name "wilcard.dev.lab Certificate" -inkey dev.lab.key -in dev.lab.crt -out dev.lab.pfx
    Import the .pfx file into local machine using default location.
    Installing Certificates
    Installing CAs' Certificate
  • Install root certificate (root-CA.crt) to Trusted Root Certification Authorities in machine level
  • Install intermediate certificate (server-CA.crt) to Intermediate Certification Authorities
  • Install IIS Express Certificate
    Install the certificate in Local Machine wide and in default location (Personal). Run this powershell with administrator privilege. Friendly name is -name parameter value when converting into PKCS12 format.
    $Ports = @(44351)
    $PfxPassword = 'pfx_password'
    #$Certificate = Get-ChildItem Cert:\LocalMachine\My | ?{ $_.FriendlyName -eq 'localhost' }
    $Certificate = Get-PfxCertificate -FilePath .\dev.lab.pfx -Password (ConvertTo-SecureString -String $PfxPassword -AsPlainText)
    $IisExpress = Get-CimInstance Win32_Product -Filter 'Name like "IIS%Express%"'
    $Ports | %{ 
        netsh http delete sslcert ipport=0.0.0.0:$Port
        netsh http add sslcert ipport=0.0.0.0:$Port  certhash="$($Certificate.Thumbprint)"  appid="$($IisExpress.IdentifyingNumber)"
    }

    `
    Installing Kestrel Certificate
  • Using environment variable
    ASPNETCORE_Kestrel__Certificates__Default__Path = path to pfx file
    ASPNETCORE_Kestrel__Certificates__Default__Password = pfx's password

  • Using appsettings.json
    json
    {
    "Kestrel": {
    "Certificates": {
    "Default": {
    "Path": "path/to/pfx/file",
    "Password": "pfx's password",
    /* or using .crt and key file */
    /*
    "Path": "path/to/crt/file",
    "KeyPath": "path/to/key/file"
    */
    }
    }
    }
    }

    Reference: Configure endpoints for the ASP.NET Core Kestrel web server

  • Using dotnet tool: dotnet dev-certs https --clean -i .\dev.lab.pfx -p the_password

  • 29

    This website collects cookies to deliver better user experience

    Creating SSL Certificate with Custom CA