If it's helpful: I wrote a PowerShell script, New-CertificateSigningRequest.ps1, that uses a simple .ini format to generate a CSR. Based on the simple .ini file, it does the following:
- Creates a .inf file for the
certreq command
- Runs
certreq -New using the .inf file to generate a CSR (.req file)
- Uses
certutil -dump to get the subject key identifier from the .req file
- Locates the certificate generated by
certreq -New in the certificate store (using the subject key identifier) and extracts the private key to a .key file (PEM format)
- Optional - Deletes the certificate generated by the
certreq -New command
The .ini file format is simple and looks like this:
[Certificate]
Subject=CN=fabrikam.local
[SubjectAlternativeNames]
1=www.fabrikam.local
With this .ini file, the script will generate a .inf with the following content:
[Version]
Signature="$Windows NT$"
[Strings]
OID_ENHANCED_KEY_USAGE="2.5.29.37"
OID_SUBJECT_ALT_NAME="2.5.29.17"
OID_PKIX_KP_SERVER_AUTH="1.3.6.1.5.5.7.3.1"
OID_PKIX_KP_CLIENT_AUTH="1.3.6.1.5.5.7.3.2"
[NewRequest]
Subject="CN=fabrikam.local"
Exportable=true
HashAlgorithm="SHA256"
KeyLength=2048
KeySpec="AT_KEYEXCHANGE"
KeyUsage="CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DIGITAL_SIGNATURE_KEY_USAGE"
MachineKeySet=true
ProviderName="Microsoft RSA SChannel Cryptographic Provider"
ProviderType=12
RequestType="PKCS10"
SMIME=false
X500NameFlags="CERT_NAME_STR_REVERSE_FLAG"
[Extensions]
%OID_ENHANCED_KEY_USAGE%="{text}%OID_PKIX_KP_SERVER_AUTH%,%OID_PKIX_KP_CLIENT_AUTH%"
%OID_SUBJECT_ALT_NAME%="{text}DNS=fabrikam.local&DNS=www.fabrikam.local"
This .inf file for certreq -New works for web servers as it adds the common name (CN) from the subject as a subject alternative name (SAN) in the request.
If the certreq -New command successfully generates the CSR (.req) file, it also exports the private key to disk in PEM format. It outputs its activities to the console using Write-Host. Sample output when using the -RemoveRequestCertificate parameter:
Created certificate request policy file 'C:\Certs\fabrikam-2025.inf'.
Running 'certreq -New' to create CSR from policy file...
The operation completed successfully
Created certificate request file 'C:\Certs\fabrikam-2025.req'.
Running 'certutil -dump' to retrieve Subject Key Identifier from CSR file...
The operation completed successfully
Certificate request Subject Key Identifier: 0123456789abcdef0123456789abcdef01234567
Found matching certificate 'Cert:\LocalMachine\REQUEST\0123456789ABCDEF0123456789ABCDEF01234567'.
Retrieved private key from 'Cert:\LocalMachine\REQUEST\0123456789ABCDEF0123456789ABCDEF01234567'.
Exported private key to file 'C:\Certs\fabrikam-2025.key'.
Removed certificate 'Cert:\LocalMachine\REQUEST\0123456789ABCDEF0123456789ABCDEF01234567'.
After submitting the CSR to a CA, you can place the certificate file (.cer) in the same directory as the private key file (.key), and then use the following command to create a PFX file:
certutil -mergePFX inputfilename.cer outputfilename.pfx
The certutil command will prompt for the PFX file password.
The New-CertificateSigningRequest.ps1 script is downloadable from GitHub gists:
https://gist.github.com/Bill-Stewart/da5256c544d38092174c4fe1262bc1d0