How-to guide · Create keys and CSRs

How to create a CSR on Windows (certreq and IIS)

In one sentence

You will have a CSR with all your names, whose private key stays inside the Windows key store, and know how to install the certificate when it returns.

Task
Create keys and CSRs
Platforms
  • Windows
  • IIS
Who it is for
Level
Practitioner · 6 steps
On this page
  1. Before you start
  2. Steps
  3. 1. Write the request file
  4. 2. Create the request
  5. 3. Check the request before you send it
  6. 4. Send the request to the CA
  7. 5. Install the certificate on the same computer
  8. 6. Or use IIS Manager
  9. Check it worked
  10. If something goes wrong
  11. Why this works
  12. Go deeper

Before you start

  • The Windows computer that will use the certificate, for example the IIS server, and a PowerShell or Command Prompt window run as administrator.
  • Every name the certificate must cover, such as shop.example.com and www.shop.example.com.
  • Your CA’s requirements: key type and size, and whether it wants extra fields.

certreq creates the private key inside the Windows key store, so it never exists as a file you could lose or leak. The flip side: the request must be completed on the same computer, because that is where the key lives.

Steps

1. Write the request file

Save this as request.inf, following Microsoft’s certreq reference:

[Version]
Signature="$Windows NT$"

[NewRequest]
Subject = "CN=shop.example.com, O=Example Shop, C=BE"
KeyAlgorithm = RSA
KeyLength = 3072
KeySpec = 1
KeyUsage = 0xa0
Exportable = FALSE
MachineKeySet = TRUE
ProviderName = "Microsoft Software Key Storage Provider"
RequestType = PKCS10
HashAlgorithm = sha256
SuppressDefaults = TRUE
FriendlyName = "shop.example.com 2026"

[Extensions]
2.5.29.17 = "{text}"
_continue_ = "DNS=shop.example.com&"
_continue_ = "DNS=www.shop.example.com"

What the lines do:

  • Subject: the subject name. Clients match host names against the SAN, not the CN, so list every name in [Extensions] too.
  • KeyAlgorithm, KeyLength: an RSA 3072-bit key. For ECDSA, use KeyAlgorithm = ECDSA_P256, remove KeyLength and set KeyUsage = 0x80 (digital signature only).
  • KeyUsage = 0xa0: digital signature and key encipherment, the usual pair for an RSA server key.
  • Exportable = FALSE: nobody can export the private key later. Set it to TRUE only if the same certificate must go to several servers.
  • MachineKeySet = TRUE: the key belongs to the computer, so services such as IIS can use it. This is why you need an elevated prompt.
  • ProviderName: the Software Key Storage Provider (CNG), which IIS on current Windows Server versions uses without trouble. A few older applications, such as some .NET Framework programs, can only use keys from a legacy CryptoAPI provider; for those, use ProviderName = "Microsoft RSA SChannel Cryptographic Provider" with ProviderType = 12, as the IIS wizard does.
  • HashAlgorithm = sha256: Windows 11 already signs requests with SHA-256 by default, but Microsoft’s reference uses sha1 as its example value, so set the hash explicitly rather than copy that.
  • SuppressDefaults = TRUE: leaves out the attributes Windows adds by default, including one that records the user, computer and process that made the request. Your CA does not need them.
  • 2.5.29.17 is the Subject Alternative Name extension. End every line except the last with &. For an IP address, use _continue_ = "IP Address=192.0.2.10".

2. Create the request

In the elevated prompt, in the folder that holds request.inf:

certreq -new request.inf request.csr
CertReq: Request Created

Windows has now created the key pair and stored a pending request under Certificate Enrollment Requests in the computer’s certificate store (open certlm.msc to see it). request.csr starts with -----BEGIN NEW CERTIFICATE REQUEST-----, which every CA accepts.

3. Check the request before you send it

certutil -dump request.csr
PKCS10 Certificate Request:
Version: 1
Subject:
    CN=shop.example.com
    O=Example Shop
    C=BE
...
Request Attributes: 1
  Attribute[0]: 1.2.840.113549.1.9.14 (Certificate Extensions)
...
    Subject Alternative Name
        DNS Name=shop.example.com
        DNS Name=www.shop.example.com

Check the subject, every DNS name, and the key size under Public Key Length. Without SuppressDefaults, you would see four request attributes, including Client Information with your account and computer name. You can also paste the CSR into the decoder at the end of this guide.

4. Send the request to the CA

Upload or paste request.csr into your CA’s form, or send it to your internal PKI team. A CSR contains no secrets. You receive the certificate as a .cer or .crt file, sometimes with the CA’s intermediate in a separate file or a .p7b bundle.

5. Install the certificate on the same computer

Windows must be able to build the chain to a trusted root before it accepts the certificate. Import the CA’s intermediate first, in the elevated prompt:

Import-Certificate -FilePath .\intermediate.cer -CertStoreLocation Cert:\LocalMachine\CA

For a private CA, its root must also be trusted on this computer, usually through Group Policy; see How to trust a private root CA on Windows. Then link the certificate to its waiting key:

certreq -accept -machine issued.cer

certreq -accept finds the pending request whose public key matches, installs the certificate in the computer’s Personal store with its key, and removes the pending request.

6. Or use IIS Manager

IIS Manager has a wizard for the same job (Microsoft Learn):

  1. Open IIS Manager, select the server, and double-click Server Certificates.
  2. In Actions, click Create Certificate Request.
  3. Fill in Common name and the organisation fields, then click Next.
  4. Keep Microsoft RSA SChannel Cryptographic Provider and choose a Bit length of 2048 or more.
  5. Enter a file name for the request and click Finish.

The wizard has no field for SANs. A public CA puts the common name into the SAN, because public certificates require it there, but an internal CA may not, and browsers then reject the certificate. For an internal CA, or for more than one name, use certreq as above.

When the certificate arrives, go back to Server Certificates, click Complete Certificate Request, choose the file from the CA and enter a friendly name. Then bind it to your site: How to install a certificate in IIS.

Check it worked

The certificate must be in the computer’s Personal store with its private key:

Get-ChildItem Cert:\LocalMachine\My |
  Where-Object Subject -like '*shop.example.com*' |
  Format-List Subject, NotAfter, HasPrivateKey, Thumbprint

HasPrivateKey : True is what you want. To test the key itself, run certutil -verifystore My <serial number>; it ends with Encryption test passed.

Try it: CSR decoderOpen the full tool

Runs in your browser. Nothing you paste is sent anywhere. A CSR is public; never paste the private key that goes with it.

PEM text, or a .csr file dropped on the box.

If something goes wrong

  • certreq -accept fails with A certificate chain could not be built to a trusted root authority. 0x800b010a (-2146762486 CERT_E_CHAINING): Windows does not have the intermediate, or does not trust the root. Import the intermediate (step 5) and make sure the root is trusted, then run certreq -accept again. Browsers report the same gap as NET::ERR_CERT_AUTHORITY_INVALID.
  • The certificate is installed but HasPrivateKey is False, or it vanishes from IIS after Complete Certificate Request: the certificate was not linked to its key. If you are on the computer that made the request, certutil -repairstore My <serial number> links them again and ends with Encryption test passed. If you are on another computer, the key is not there: create a new request on the right computer.
  • Access is denied when you run certreq -new: MachineKeySet = TRUE needs an elevated prompt.
  • The CA rejects the request: check the key size and hash algorithm, and that each name is one the CA can validate.
  • Browsers show NET::ERR_CERT_COMMON_NAME_INVALID for one of your names: that name is missing from the SAN. Add it to [Extensions] and request again.
  • You need the same certificate on another server later: with Exportable = FALSE you cannot export the key. Create a request on that server too, or plan an exportable key and move it as a PFX.

Why this works

A CSR is a PKCS #10 structure, RFC 2986 (PKCS #10): your public key and requested names, signed with the private key to prove you hold it. On Windows, certreq asks a key storage provider to create the key pair and keeps a pending request that points to the key. When the certificate comes back, Windows matches its public key to that pending request and links the two, which is why the computer matters. Asking for a certificate explains the CSR, Names and jobs explains SANs and key usage, and Certificate chains explains why Windows needs the intermediate.

Go deeper

Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.

Last reviewed Edition 0.9