19

I tried to follow the website below for instructions on how to generate the CSR for my web server:

http://www.entrust.net/knowledge-base/technote.cfm?tn=8649

However, it only generates the CSR. Where is the private key? I was told that the key is generated at the time of CSR generation.

I am using Windows 10. I plan to use node.js Express. Are there alternative tools we can use to generate CSR on Windows 10?

mikemaccana
  • 3,710

2 Answers2

18

It's stored in the Windows certificate store. When you import the signed certificate, you will find you have a corresponding private key. It matches them by modulus, if I recall.

You can get a list of the private keys you have as a result of certificate enrollment requests (such as you made with certreq) by running certmgr.msc for the computer account (or simply certlm.msc for Windows 2012R1 or Windows 8 onwards).

The keys are in the Certificate Enrollment Requests folder.

The easiest thing to do if you need to use the certificate without using the API is to import the certificate, export it, and use openssl to transform the resulting PKCS5 into a PEM certificate and key.

You can also use openssl to generate keys and certificate requests, and if you plan to use them in PEM format on the filesystem rather than using the Windows API, you might as well do that.

Falcon Momot
  • 25,584
0

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:

  1. Creates a .inf file for the certreq command
  2. Runs certreq -New using the .inf file to generate a CSR (.req file)
  3. Uses certutil -dump to get the subject key identifier from the .req file
  4. 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)
  5. 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