bg-tutorials

Come generare un codice di firma Csr su Windows usando certreq

The Windows certreq.exe utility builds a Certificate Signing Request (CSR) from a plain-text policy file, normally called request.inf. It is the scriptable way to create a request on Windows without clicking through the Certificates snap-in. This guide shows the policy file and the commands, and it starts with the rule that decides whether a certreq request will be accepted at all, because for code signing that rule changed in 2023.

First check: where the key is allowed to live

Since June 1, 2023, the CA/Browser Forum Code Signing Baseline Requirements have required the private key of every publicly trusted code signing certificate, standard (OV) and Extended Validation (EV) alike, to be generated and kept in a hardware crypto module meeting FIPS 140-2 Level 2, Common Criteria EAL 4+, or an equivalent standard, and the key must be non-exportable. EV code signing always worked this way; the 2023 change extended the same rule to standard certificates.

That rule is about the key, not about the tool. certreq is not banned, but the provider you name in the policy file decides whether the request is usable:

  • certreq pointed at a software provider (for example Microsoft Software Key Storage Provider, or any of the legacy Microsoft CSPs) creates the key in the Windows profile on disk. No public Certificate Authority will issue a code signing certificate against that request.
  • certreq pointed at a hardware Key Storage Provider (a token, smart card, or HSM whose vendor installs a KSP on Windows) creates the key inside the device. That request is valid, and it is how several CAs expect you to supply a CSR when you use your own hardware.
  • certreq against an internal or enterprise CA is unaffected. Your own policy governs key storage for certificates that only your organization trusts, so a software key is a decision you make rather than one the Baseline Requirements make for you.

There is one more route that skips the CSR entirely. If you order a certificate with token plus shipment as the code signing delivery method, the CA generates the key and the request on a certified token and mails you the token with the certificate already loaded. In that case there is nothing for certreq to do, and this guide does not apply.

If you generate the key on hardware you own, most CAs also want an attestation file, which is proof signed by the device that the key was created there and cannot leave. certreq does not produce attestation. Get it from your device tooling, and follow the guide that matches your hardware: YubiKey 5 FIPS CSR generation and attestation or the Luna Network Attached HSM v7.x CSR and attestation guide.

Step 1: Find the exact provider name

The ProviderName value in the policy file has to match the provider’s display name character for character, so read it off the system rather than typing it from memory. Open a Command Prompt and run:

certutil -csplist

The output lists every cryptographic provider registered on the machine, both the legacy CSPs and the newer CNG Key Storage Providers. Plug in your token or install your HSM client software first, otherwise its provider will not appear. Look for a name supplied by your hardware vendor, or for Microsoft Smart Card Key Storage Provider, which Windows uses for smart cards and many USB tokens that ship a minidriver instead of their own KSP.

Two provider names to avoid for this job. Microsoft RSA SChannel Cryptographic Provider appears in many copied certreq templates, including older versions of this page, because it is the example Microsoft uses in its generic certreq documentation. It is the Schannel provider, meant for TLS, and it is a legacy CSP that keeps the key in software. Microsoft Software Key Storage Provider is the sensible modern software choice, but it is still software, so use it only for internal signing or for rehearsing the syntax.

Step 2: Build the request.inf policy file

Open Notepad or any plain-text editor, paste the block below, edit the Subject and ProviderName lines, and save it as request.inf. In Notepad’s Save dialog set Save as type to All Files so it does not become request.inf.txt.

[Version]
Signature="$Windows NT$"

[NewRequest]
; Replace with your own legal details.
; C is the two-letter country code, S is the state or province,
; L is the city, O is the registered organization name,
; CN is the identity that will appear as the publisher.
Subject = "CN=Your Company Ltd, O=Your Company Ltd, L=San Jose, S=California, C=US"

KeyAlgorithm = RSA
KeyLength = 3072
KeyUsage = 0x80
HashAlgorithm = SHA256
RequestType = PKCS10
Exportable = FALSE
MachineKeySet = FALSE

; Must match a provider listed by: certutil -csplist
ProviderName = "Microsoft Smart Card Key Storage Provider"

[EnhancedKeyUsageExtension]
; 1.3.6.1.5.5.7.3.3 is the code signing extended key usage
OID = 1.3.6.1.5.5.7.3.3

Two things break this file more often than anything else. Use straight double quotes, not the curly quotes a word processor produces, because certreq cannot parse them. And keep each comment on its own line starting with a semicolon rather than trailing after a value, so no parser has to decide where the value ends.

What each setting does

  • Subject holds your identity as a Relative Distinguished Name string. A code signing certificate identifies a publisher, not a website, so there is no domain name and no Subject Alternative Name here. Windows accepts both S= and ST= for the state or province (both map to the same object identifier, 2.5.4.8), which is worth knowing if you are used to OpenSSL, where ST= is the usual spelling. Enter the details exactly as they appear in your official registration records, because the CA validates them.
  • KeyAlgorithm selects the algorithm. RSA is the safe default. Key Storage Providers also accept ECDSA_P256, ECDSA_P384 and ECDSA_P521, but check with your CA before submitting an elliptic-curve code signing request.
  • KeyLength sets the RSA key size. The Baseline Requirements have set a floor of 3072 bits for code signing since June 1, 2021. You can raise it to 4096 if the device supports it, so confirm against your token’s specification rather than assuming: the Windows provider will accept a large value that the hardware behind it cannot generate.
  • KeyUsage is a hexadecimal bit field. 0x80 is digitalSignature, which RFC 5280 names as the key usage bit consistent with the code signing purpose. Older templates carry 0xa0, which adds keyEncipherment, an encryption bit a signing key has no use for. Many CAs set the final key usage from their own profile regardless of what you request, but there is no reason to ask for the wrong one.
  • HashAlgorithm sets the digest used to sign the request. SHA-1 has been prohibited for code signing since June 1, 2021, so SHA256 is the minimum.
  • RequestType set to PKCS10 produces the standard CSR that public CAs expect. The other values (PKCS7, CMC, Cert and SCEP) are for renewals, key archival, self-issued certificates and network device enrollment.
  • Exportable set to FALSE keeps the private key from being extracted with the certificate. On compliant hardware the device enforces this anyway and the setting is a formality, but leaving it TRUE, as many old templates do, states the opposite of what a code signing key is supposed to be.
  • MachineKeySet set to FALSE creates the key in the current user’s context, which is also the certreq default. Set it to TRUE only if the key must belong to the computer rather than to you, and in that case run every certreq command from an elevated Command Prompt.
  • ProviderName decides where the key is created, which is the single most important line in the file. See step 1.
  • [EnhancedKeyUsageExtension] requests the code signing extended key usage. The object identifier 1.3.6.1.5.5.7.3.3 is id-kp-codeSigning from RFC 5280, defined there as signing of downloadable executable code. Microsoft’s certreq reference documents extensions in an [Extensions] section, where the equivalent is 2.5.29.37 = “{text}1.3.6.1.5.5.7.3.3”, while its current Windows Server enrollment guides still use the section above. Both forms work.

Settings older templates include, and why they are not here

Templates copied around the web carry a longer list. Most of those lines are inherited from Microsoft’s generic web-server example and do nothing useful for a code signing request:

  • KeySpec and ProviderType belong to the legacy CryptoAPI world. Microsoft documents the key specification as applying only to legacy providers created with CryptoAPI, and ProviderType selects a legacy CSP by capability, so neither belongs in a KSP request. If you genuinely have to use a legacy CSP, note that KeySpec = 1 is AT_KEYEXCHANGE, a key for signing and encryption, while a signature-only key is KeySpec = 2, AT_SIGNATURE. Old code signing templates almost always show 1, which is not what a signing certificate wants.
  • SMIME set to TRUE adds a secure email capabilities extension. It is irrelevant to code signing, and setting it to FALSE just restates the default.
  • PrivateKeyArchive only takes effect when RequestType is CMC, so it does nothing in a PKCS10 request.
  • UseExistingKeySet set to FALSE is the default. Set it to TRUE only when you are reusing an existing key, and then you must also supply RenewalCert or KeyContainer and must not set Exportable.
  • UserProtected is not in Microsoft’s current list of policy file keys. If you want Windows to prompt for a password whenever the key is used, the documented setting is KeyProtection. Hardware tokens handle this themselves with a PIN.

For an internal or enterprise CA, where a software key is acceptable, change one line and leave the rest as it is:

ProviderName = "Microsoft Software Key Storage Provider"

Step 3: Generate the CSR

Press the Windows key + R, type cmd and press Enter. Change into the folder holding request.inf, then run:

certreq -new request.inf codesign.csr

certreq creates the key pair through the provider you named and writes the base64-encoded request to codesign.csr. With a token or smart card you will be prompted for the device PIN at this point, which is the visible sign that the key is being created on the hardware rather than on disk. Add -f if you are overwriting an output file from a previous attempt.

The private key stays on the machine (or in the device) as a pending request. Do not delete the pending request, reimage the computer, or wipe the token while you wait for the certificate, because the issued certificate is useless without the key that matches it.

Step 4: Check the CSR before submitting it

A validation failure caused by a typo costs days, so read the request back before you paste it into an order form:

certutil -dump codesign.csr

Confirm four things in the output: the Subject line shows your organization details spelled exactly as they are registered; the public key length is 3072 bits or more; the signature algorithm is SHA256; and the requested extensions include the code signing object identifier 1.3.6.1.5.5.7.3.3. If any of those is wrong, correct request.inf and run step 3 again rather than editing the CSR by hand. You can also paste the request into the CSR decoder to read the same details in a browser.

Then open codesign.csr in a plain-text editor and copy the entire contents, including the BEGIN and END marker lines, into the enrollment form. Do not be thrown if those markers read NEW CERTIFICATE REQUEST rather than the CERTIFICATE REQUEST wording OpenSSL produces. The encoded request between them is the same PKCS#10 structure either way. If your hardware also produced an attestation file, submit it alongside the CSR.

Common certreq problems

  • The policy file fails to parse. Almost always curly quotation marks pasted from a word processor, or a file saved as request.inf.txt by Notepad. Retype the quotes in a plain-text editor and confirm the real file name with dir request.*.
  • The provider cannot be found. The ProviderName string does not match the display name exactly. Run certutil -csplist again and copy the name from that output, and check the token is connected and its driver installed.
  • Key generation fails on the device. The requested KeyLength is beyond what the hardware can generate, or the token has no free key slot. Check the device specification and clear unused slots with the vendor’s management tool.
  • certreq -accept reports no matching request. You are in the wrong user or machine context, or the pending request was removed. Add -user or -machine. If the pending request is genuinely gone, the key is unrecoverable and the certificate has to be reissued against a new CSR.
  • The CA rejects the CSR. For a public code signing order this usually means the key was created in software, or the attestation is missing or does not match the CSR. Regenerate with a hardware provider and submit both files together.

Frequently Asked Questions

Can I still use certreq to create a code signing CSR?

Yes, provided the policy file names a hardware Key Storage Provider so the key is created inside a token or HSM. Since June 1, 2023 the CA/Browser Forum has required the private key of every publicly trusted code signing certificate to be generated and held in hardware meeting FIPS 140-2 Level 2, Common Criteria EAL 4+, or equivalent, so a certreq request built against a software provider will be rejected by a public CA. For an internal or enterprise CA, a software provider is still fine.

Which ProviderName should I put in request.inf?

Run certutil -csplist with the token connected and copy the display name from the output. It is usually a name supplied by your hardware vendor, or Microsoft Smart Card Key Storage Provider for devices that use a Windows minidriver. Do not use Microsoft RSA SChannel Cryptographic Provider, which appears in many copied templates: it is the TLS provider and it stores the key in software.

Why does my request.inf file fail to parse?

The usual cause is curly quotation marks. If the file was written in Word, or the text was copied from a web page that applied smart quotes, the quotes around the Subject and ProviderName values are typographic characters that certreq cannot read. Retype them as straight double quotes in Notepad. The second common cause is Notepad saving the file as request.inf.txt, which you can confirm with dir request.*.

Should KeySpec be 1 or 2?

Neither, if you use a Key Storage Provider: CNG keys have no key specification, so leave the setting out. It applies only to the legacy CryptoAPI providers, where 1 is AT_KEYEXCHANGE, a key usable for signing and encryption, and 2 is AT_SIGNATURE, a signature-only key. Older code signing templates show KeySpec = 1, which is the encryption-capable value and not what a signing certificate needs.

What does the OID 1.3.6.1.5.5.7.3.3 mean?

It is id-kp-codeSigning, the extended key usage that RFC 5280 defines as signing of downloadable executable code. Including it in the policy file tells the CA the certificate is for code signing rather than for a web server or email. The same document names digitalSignature as the key usage bit consistent with that purpose, which is why the policy file above sets KeyUsage to 0x80.

What key size and hash does a code signing CSR need?

RSA 3072 bits or larger, signed with SHA-256 or stronger. Both floors have applied since June 1, 2021 under the Code Signing Baseline Requirements, which also prohibit SHA-1. Check that your token can generate the size you ask for before running certreq, because the Windows provider will accept a value the hardware behind it cannot produce.

certreq -accept says there is no matching request. What now?

You are almost certainly in a different context from the one that created the request. The policy file above uses MachineKeySet = FALSE, so the pending request belongs to the user who ran certreq -new. Sign in as that user, or add -user or -machine to name the context explicitly. If the pending request has actually been deleted, the private key cannot be recovered and the certificate has to be reissued against a fresh CSR.

Can I export the certificate to a PFX file afterwards?

Only when the key was created in software, which for code signing means an internal CA. A key generated on compliant hardware is non-exportable, so there is no PFX to produce and you sign with the token connected instead. Older guides that end by exporting a public code signing certificate to PFX describe the pre-2023 workflow.

Other ways to create this request: OpenSSL, Microsoft Management Console, Java Keystore and macOS Keychain Access. See also the overview of CSR generation for code signing certificates, the full set of code signing tutorials, and other ways to generate a CSR.

Risparmia il 10% sui certificati SSL ordinando oggi stesso da SSL Dragon!

Emissione rapida, crittografia avanzata, affidabilità del browser al 99,99%, assistenza dedicata e garanzia di rimborso entro 25 giorni. Codice coupon: SAVE10

Un'immagine dettagliata di un drago in volo
Scritto da

Scrittore di contenuti con esperienza, specializzato in certificati SSL. Trasforma intricati argomenti di cybersicurezza in contenuti chiari e coinvolgenti. Contribuisci a migliorare la sicurezza digitale attraverso narrazioni d'impatto.