Signing Windows RDP Files with a Self-Signed Certificate (1-1. Creating the Certificate)

Windows Notes

Opening a Windows .rdp file can display a security warning asking you to verify the publisher of the remote connection.

This article creates a self-signed certificate for RDP file signing with PowerShell, exports the public certificate as a .cer file, and saves a private-key backup as a .pfx file.

Because the complete procedure is long, it is divided into two articles:

  1. This article: Create and back up the RDP signing certificate
  2. 1-2. Signing the RDP file: rdpsign, Group Policy, and a drag-and-drop batch file

RDP file signing and the RDP server TLS certificate are different

The certificate created here identifies the publisher of the .rdp file itself.

It has a different purpose from the RDP server’s TLS certificate, which is involved in warnings such as “The identity of the remote computer cannot be verified.” Creating this certificate does not resolve server-certificate warnings.

Create the working directory

This procedure stores the public certificate and the batch file created in part 1-2 under C:\RDPs.

Open PowerShell and run:

New-Item -ItemType Directory -Path 'C:\RDPs' -Force

The final layout is:

C:\RDPs\
├─ MyRdpPublisher.cer
└─ sign_rdp_dragdrop.bat

Because a PFX backup contains the private key, do not keep it permanently in this public working directory. Store it separately in a secure location.

Create the self-signed RDP signing certificate

Run the following command in Windows PowerShell:

$params = @{
    Type              = 'CodeSigningCert'
    Subject           = 'CN=My RDP Publisher'
    FriendlyName      = 'My RDP Publisher'
    CertStoreLocation = 'Cert:\CurrentUser\My'
    KeyAlgorithm      = 'RSA'
    KeyLength         = 2048
    HashAlgorithm     = 'SHA256'
    KeyExportPolicy   = 'Exportable'
}

$cert = New-SelfSignedCertificate @params

The new certificate object is stored in $cert.

Microsoft Learn documents CodeSigningCert as an accepted Type, DigitalSignature as a key usage, and RSA or ECDSA as available key algorithms for New-SelfSignedCertificate. This procedure uses CodeSigningCert to express the publisher-signing purpose and selects RSA 2048-bit for compatibility.

Because CodeSigningCert configures the signing purpose and Code Signing EKU, the command does not duplicate the same configuration through KeyUsage or TextExtension. Microsoft does not document KeyAlgorithm and KeyLength as rdpsign-specific requirements; they are specified here to make the certificate creation conditions reproducible.

HashAlgorithm = 'SHA256' selects the hash algorithm used to sign the self-signed certificate itself. It is separate from the certificate thumbprint passed to rdpsign /sha256 in part 1-2.

KeyExportPolicy = 'Exportable' allows the private key to be exported to a PFX file for Windows reinstallation or migration. If you do not need a backup and do not want the private key to be exportable, decide that policy before creating the certificate.

NotAfter is omitted. Microsoft Learn states that the default expiration is one year after creation. If a different lifetime is required, decide on an appropriate period and explicitly specify -NotAfter.

Verify the certificate

Immediately after creation, inspect the required fields:

$cert | Select-Object Subject, Thumbprint, HasPrivateKey, NotBefore, NotAfter

Confirm the following:

  • Subject is CN=My RDP Publisher.
  • A Thumbprint is displayed.
  • HasPrivateKey is True.
  • NotBefore and NotAfter show the expected validity period.

It is especially important that HasPrivateKey = True. An RDP file cannot be signed without the private key.

After reopening PowerShell, locate the certificate by subject:

$cert = Get-ChildItem 'Cert:\CurrentUser\My' |
    Where-Object Subject -eq 'CN=My RDP Publisher' |
    Sort-Object NotBefore -Descending |
    Select-Object -First 1

$cert | Select-Object Subject, Thumbprint, HasPrivateKey, NotBefore, NotAfter

Multiple certificates can have the same subject, so do not use the first result blindly. Check the validity period and thumbprint as well.

Inspect the Code Signing EKU with:

$cert.EnhancedKeyUsageList | Select-Object FriendlyName, ObjectId

For a GUI check, run certmgr.msc, open Personal → Certificates, and then open My RDP Publisher. On the General tab, also confirm that Windows reports that you have a private key corresponding to the certificate.

Export the public certificate to CER

Export the public certificate with:

Export-Certificate `
    -Cert $cert `
    -FilePath 'C:\RDPs\MyRdpPublisher.cer'

As documented by Microsoft Learn, a single .cer file exported with Export-Certificate does not include the private key.

Verify the file:

Get-Item 'C:\RDPs\MyRdpPublisher.cer'

Why the CER file alone cannot sign an RDP file

MyRdpPublisher.cer is a public certificate and normally contains no private key. Copying only this file to another PC does not let that PC sign RDP files as the same publisher.

The certificate that rdpsign uses for the actual signature must be:

  • The same certificate represented by the .cer file
  • Associated with its private key
  • Stored under CurrentUser\My or LocalMachine\My

The batch file in part 1-2 reads the .cer file to identify the certificate by thumbprint. The actual signature still requires the private key in the Windows certificate store.

MyRdpPublisher.cer
        └─ Read public information and thumbprint

Cert:\CurrentUser\My\<Thumbprint>
        └─ Use the private key for the actual signature

Back up the private key as PFX

Reinstalling Windows removes the private key from the certificate store. To keep signing as the same publisher, back up the certificate and private key as a PFX file.

Enter the password interactively instead of putting it directly in a command or script:

$pfxPassword = Read-Host 'PFX password' -AsSecureString

Export-PfxCertificate `
    -Cert $cert `
    -FilePath 'D:\SecureBackup\MyRdpPublisher-backup.pfx' `
    -Password $pfxPassword

D:\SecureBackup is only an example. Use an access-controlled storage location, and do not store the PFX and its password together in plain text.

To restore it, import the PFX into CurrentUser\My:

$pfxPassword = Read-Host 'PFX password' -AsSecureString

Import-PfxCertificate `
    -FilePath 'D:\SecureBackup\MyRdpPublisher-backup.pfx' `
    -CertStoreLocation 'Cert:\CurrentUser\My' `
    -Password $pfxPassword

After importing, confirm again that HasPrivateKey = True.

Protect the private key

Anyone with the private key can sign RDP files as My RDP Publisher. Store the PFX separately from the public .cer file and batch file, and do not give it to third parties.

Use a self-signed certificate only on computers you manage or in a test environment. When distributing RDP files across an organization, follow its certificate policies and use a managed publisher certificate.

Next step

After creating the certificate and public CER file, continue with:

Part 1-2 covers rdpsign, the trusted RDP publisher Group Policy setting, and a batch file for drag-and-drop signing of multiple RDP files.

References