<!-- https://pkizerotohero.com/guides/create-csr-windows/ | Markdown mirror of the HTML page | PKI Zero to Hero, by Duyutech BV -->

> Create a CSR on Windows with certreq and an INF file, including SANs, or with IIS Manager, then install the issued certificate on the same computer.

Source: https://pkizerotohero.com/guides/create-csr-windows/ · Last reviewed: 2026-10-20

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](https://pkizerotohero.com/guides/#task-create)

Platforms

- Windows
- IIS

Who it is for

- [IT ops](https://pkizerotohero.com/start/#itops)
- [Developer](https://pkizerotohero.com/start/#developer)

Level

Practitioner · 6 steps

## 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](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1):

```text
[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](https://pkizerotohero.com/handbook/glossary/#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`:

```powershell
certreq -new request.inf request.csr
```

```text
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

```powershell
certutil -dump request.csr
```

```text
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:

```powershell
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](https://pkizerotohero.com/guides/add-root-ca-windows/). Then link the certificate to its waiting key:

```powershell
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](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc732906\(v=ws.10\))):

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](https://pkizerotohero.com/guides/install-certificate-iis/).

## Check it worked

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

```powershell
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`.

*Interactive tool: CSR decoder (runs in the browser at [/tools/csr/](https://pkizerotohero.com/tools/csr/))*

## 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`](https://pkizerotohero.com/errors/chrome-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`](https://pkizerotohero.com/errors/chrome-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](https://pkizerotohero.com/guides/convert-pfx-pem/).

## 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](https://pkizerotohero.com/handbook/csr/) explains the CSR, [Names and jobs](https://pkizerotohero.com/handbook/names-and-key-usage/) explains SANs and key usage, and [Certificate chains](https://pkizerotohero.com/handbook/certificate-chains/) explains why Windows needs the intermediate.

## Go deeper

- [Microsoft Learn: certreq](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1): every INF key, including `SuppressDefaults` and the SAN syntax.
- [Microsoft Learn: certutil](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil): `-dump`, `-verifystore` and `-repairstore`.
- [Microsoft Learn: Request an Internet server certificate (IIS 7)](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc732906\(v=ws.10\)) and [Complete a certificate request](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc771816\(v=ws.10\)): the IIS Manager steps.
- [RFC 2986](https://www.rfc-editor.org/rfc/rfc2986): the PKCS #10 request format.

**Early edition.** Checked against the standards; an independent expert review is in progress. Found a mistake? [Tell us](https://pkizerotohero.com/contact/?topic=content-error&page=/guides/create-csr-windows/).

Last reviewed 20 October 2026Edition 0.9

## Keep going

### Learn why it works

- [Chapter 10: Asking for a certificate: key generation and the CSR](https://pkizerotohero.com/handbook/csr/)
- [Chapter 9: Names and jobs: SANs, wildcards, key usage and the CA flag](https://pkizerotohero.com/handbook/names-and-key-usage/)
- [Chapter 13: Certificate chains and path validation](https://pkizerotohero.com/handbook/certificate-chains/)

### Error pages

- [NET::ERR\_CERT\_COMMON\_NAME\_INVALID](https://pkizerotohero.com/errors/chrome-err-cert-common-name-invalid/)
- [NET::ERR\_CERT\_AUTHORITY\_INVALID](https://pkizerotohero.com/errors/chrome-err-cert-authority-invalid/)

### Tools

- [CSR decoder](https://pkizerotohero.com/tools/csr/): Check a certificate signing request before you send it to a CA.

### Topics

- [Certificates](https://pkizerotohero.com/topics/certificates/)

## More guides: Create keys and CSRs

- [How to create a key and a CSR with OpenSSL (with SANs)](https://pkizerotohero.com/guides/create-csr-openssl/)
- [How to create a CSR with Java keytool](https://pkizerotohero.com/guides/create-csr-java-keytool/)
