How to provide a verified server certificate for Remote Desktop (RDP) connections to Windows 10


We have a Windows 10 Pro machine at our office which has an open port to the internet for incoming remote desktop connections (a ‘host’). It is well protected by complex password and limited number of permitted attempts and only TLS 1.1 or higher, but it doesn't present an externally-verified SSL certificate, only the self-generated self-signed one that Remote Desktop Services provides, and this gives us two problems:

  1. We cannot be fully confident when connecting remotely we really are connecting to this machine and not some hijacked connection.
  2. Our site fails PCI-DSS 3.1 compliance check (required because we use there a point-of-sale debit/credit card machine that connects via internet). The check reports fatal errors on this internet-facing remote desktop port: 'SSL Self-Signed Certificate' and 'SSL Certificate with Wrong Hostname'.

How do I get a Windows 10 Pro (or Windows 7 / 8 / 8.1 Pro) machine acting as server/host to present a proper SSL certificate for Remote Desktop verification?


Answers:


You can set this host machine to use and present your (existing, purchased) externally-verified SSL certificate thus (instructions probably also work for Windows 8 & 8.1, may or may not work for Windows 7) (parts of this based on a Microsoft KB 2001849):

First, you need to have purchased a genuine verified ssl certificate.

If you have this certificate in pkcs12 format file (e.g. pfx extension) you can view SHA1 fingerprint using Linux or Cygwin thus (you will need it below):

openssl pkcs12 -in mysite.pfx -nodes|openssl x509 -noout -fingerprint

Alternatively if you have the individual certificate files in your Linux server at /etc/ssl (/etc/ssl/certs/mysite.crt, /etc/ssl/mysite.ca-bundle and /etc/ssl/private/mysite.key) you can create pfx file and obtain SHA1 fingerprint thus:

  1. Create pfx file for your certificate, if you don’t already have one (here: mysite.pfx) – set a good password when requested:

    sudo openssl pkcs12  -export -out mysite.pfx -inkey /etc/ssl/private/mysite.pem -in /etc/ssl/certs/mysite.crt -certfile /etc/ssl/mysite.ca-bundle
    
  2. Move or copy this pfx file as required so that it is accessible by your Windows host machine.

  3. View SHA1 fingerprint of the key (you will need this below):

openssl x509 -in /etc/ssl/certs/mysite.crt -noout -fingerprint

Import pkcs12 format (e.g. pfx) file into Windows host machine’s personal certificates store:

  1. Start > Run > mmc
  2. File > Add Remove Snap-in > Certficates > Add > Computer Account > Local Computer > OK
  3. In the left-hand window right-click on Certificates (Local Computer)Personal, choose All Tasks/Import…
  4. Locate the pfx file and import it, I suggest that for security reasons you don’t make it exportable.
  5. Expanding your Personal/Certificates you should now see 3 certificates, one of which is your site certificate (e.g. mysite.com). Right-click on this site certificate and right-click, choose All Tasks / Manage Private Keys…
  6. Add user ‘NETWORK SERVICE’ with Read permission only (not Full Control), then Apply
  7. Close mmc

Use regedit to add a new Binary Value called SSLCertificateSHA1Hash at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp. The value it needs is the SHA1 fingerprint of the certificate obtained above: right-click on the new value, choose Modify and then type in the hex codes sequentially (without colons or spaces or commas, letters are not case-sensitive) – there are 20 hex pairs in all (40 characters).

You may need to reboot the host machine, or restart Remote Desktop Services (from Services.msc) before it will work.

Now, after making a remote desktop connection to this host using the correct site name (e.g. mysite.com) you should see a locked padlock on the left-hand side of the top connection bar: clicking on this shows that the identity of the remote computer was verified. A port that is open from the internet through to this host should now pass PCI-DSS 3.1 hostname testing.