none
RDP with custom certificate in Windows 7? (No tsconfig.msc or Group Policy setting) RRS feed

  • 質問

  • I am trying to configure Remote Desktop in Windows 7 RTM using SSL/TLS authentication and encryption, with a custom certificate (not the default self-signed certificate) and private key. I installed a specific certificate and private key into the Local Computer store under Remote Desktop > Certificates. However, I do not see any way to tell Remote Desktop/Terminal Services to use that cert and key. How do I select that specific cert and key?

    I tried to connect to the Windows 7 machine from Windows XP running the Remote Desktop Connection Client (mstsc.exe) 6.0. It continues to report the self-signed certificate when connecting, not the custom cert. I tried removing the self-signed certificate and restarting, but the self-signed certificate gets regenerated (new issued time, and new SHA-1 fingerprint).

    tsconfig.msc is missing: a post on the MS blogs suggests that it is only available in the Server editions of Windows.

    In gpedit.msc (Group Policy), I found Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Security, but I do not know what to put in for "Server Authentication Certificate Template", or if that is even the right setting to manipulate. I just want to specify the specific certificate and private key, such as by SHA-1 fingerprint, or by selecting from a drop-down list. Is this possible?

    2009年8月25日 9:25

すべての返信

  • I think i saw it somewhere around there with Certification Print ID set up for remote desktop services not sure if we'r talking about the same thing but just in case i'll check it later from my other PC ...
    regards,
    RR

    • 回答の候補に設定 Derek_1001 2014年2月7日 12:53
    2009年8月25日 14:52
  • Have not tried myself but you can try changing the registry key "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\SelfSignedCertificate" to the thumbprint of my your custom certificate, let us know if that works.......

    Note:- Backup your registry before following the above...
    2009年8月25日 17:26
  • Thanks Mukesh. I tried that, and unfortunately it did not work.

    Set data to the SHA-1 fingerprint of my certificate: did not work.
    Set data to the SHA-1 fingerprint of my certificate, and restarted Remote Desktop Services: did not work; SelfSignedCertificate got overridden and a new certificate and key were generated. When I connected with mstsc, it reported the new self-signed certificate.
    Set data to the SHA-1 fingerprint of my certificate, and added Deny Set Value ACL on SYSTEM (and on Everyone as well): Remote Desktop disables SSL/TLS entirely, falling back to the old RDP encryption. mstsc reports that it cannot authenticate at all (indicating RDP encryption).

    Any other ideas? I wonder what the Windows Server 2008 R2 registry keys are, if anything.
    2009年8月25日 19:18
  • Well in w2k3 you have Terminal Services which is not available in Client version, so the
    registry keys from a server to client which does not have or supports the service will not work...
    You sure the certificate which you are importing is meant for that machine.
    2009年8月26日 7:07
  • I'm having exactly the same issue. While it's true that "Terminal Services" is not a feature of client versions of Windows you can of course remote desktop to them and get annoying little warnings because the self-signed cert they're using isn't from a trusted authority. Clearly it'd be more nice to be able to reach in and set that cert to a "real" one. I'm about to try manually copying tsconfig.msc to the client box and see what happens.

    OK, the blunt object approach didn't work. No amount of copying files evilly out of System32 on a server box into a folder on the client box resulted in being able to launch tsconfig.msc. Apparently thought is required.
    (MS Employee)
    2009年8月26日 17:19
  • I opened a support case with Microsoft, and figured out the solution with them. The main insight is to create a REG_BINARY value SSLCertificateSHA1Hash. However, there are other nuances, so read on.

    First, import your desired SSL certificate and private key into the Local Machine/Personal store. You can do this using MMC: File > Add or Remove Snap-Ins > Certificates > "Computer account". Then, open Personal > Certificates, and add your .p12 file. If you use certutil, use certutil -importPFX. (You may need to be at an elevated command prompt.) If you wish to use a particular Cryptographic Service Provider, which you can do with the -csp argument. For example, you can put the key on a special hardware token, or you may want to use the newer NCRYPT service provider ("Microsoft Software Key Storage Provider") instead of the older CryptoAPI service providers (such as "Microsoft Enhanced Cryptographic Provider V1.0"). You cannot choose a CSP if you use the MMC/CryptoAPI UI Import Wizard. This is what the support representative at MS said:

    I hope this is what you are looking for. When we import the certificate+private key (PFX/p12) file – we can actually specify a switch.

    CertUtil –importPFX –csp Provider

    Certutil –ImportPFX uses PFXImportCertStore – but only to load the PFX into a memory store, to make the keys programmatically accessible.
    To move the keys to another CSP, the –csp ProviderName option must be used (a smart card CSP can be specified).
    It then enumerates certs with private keys in the PFX-imported cert store, and transfers each key to the specified CSP.
    For each cert+key pair in the PFX, certutil exports the private key blob using CryptAcquireContext + CryptGetUserKey + CryptExportKey, then re-imports it into the target CSP using CryptAcquireContext + CryptImportKey, then it sets the certificate on the smart card key container using CryptSetKeyParam.

    Now then, look at your certificate and key, and take note of two pieces of information: the Cert Hash(sha1) and the key container information.

    The cert hash is just the SHA-1 hash of the certificate. This will be a 160-bit (20-byte) value. You can get this by double-clicking on the certificate in MMC, or using certutil -store My.

    Open regedit and go to the following key:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

    Create a REG_BINARY value with the name SSLCertificateSHA1Hash. Open it up, and enter the 20 bytes exactly as you saw it. This setting will tell Terminal Services (Remote Desktop Services) to use the SSL certificate identified by that SHA-1 hash.

    Simple enough, right? Not so fast. Remote Desktop Services in Windows 7 runs under the NetworkService (NT AUTHORITY\NETWORK SERVICE) account, not the LocalSystem (NT AUTHORITY\SYSTEM) account. If you leave the configuration as-is, you will not be able to connect to Remote Desktop, and will see cryptic cryptography and security error messages in the Windows Event log! You need to grant "generic read" access to the private key associated with this certificate to the Network Service account.

    There are two ways to do this, and the result is the same although you will want to understand what you are doing so that you do not give too much access to too many user accounts. Basically, you modify the ACL on the private key (and just that private key) so that when the Remote Desktop process accesses it, the read will succeed.

    In MMC, right-click on the certificate, then: All Tasks > Manage Private Keys... You will see the ACL Editor UI for "Permissions for {FriendlyName} private keys", where {FriendlyName} is the name of your cert (which you can configure). There are only two options: "Full Control" and "Read". Add "NETWORK SERVICE" as a user, and give NETWORK SERVICE Read access.

    If you are using certutil, you need to do a little more legwork but it will pay off. Execute the command certutil -store -v My. This will dump information on the Personal store in verbose mode, including all of the gory details about the CSP key container. You will see the CSP name and parameters, and the "Unique container name," which will probably look like a SHA-1 hash plus underscore plus GUID. Example:
    Unique container name: deadbeef012034567890bf23ff2572d9_cafebabe-c76b-4bbf-0000-ffffffffffff

    You will also see the permissions on that key. These permissions will say "[Allow/Deny] [Read/Write/Full Control] [SID name]".

    Use Windows Explorer to go to:
    C:\ProgramData\Microsoft\Crypto
    or equivalently:
    C:\Users\All Users\Microsoft\Crypto
    (All Users is a symlink to ProgramData.)

    If you are using NCRYPT/CNG, your keys will be under the Keys subfolder. You should see a file with the same name as the unique container name. It has no extension, and has the System attribute set.

    If you are using CAPI 1.0, your keys will likely be under the RSA\MachineKeys subfolder. Again, the same thing applies: you should see a file with the unique container name, with the System attribute set.

    Set the ACL on this file to allow generic read access for NT AUTHORITY\NETWORK SERVICE. (Generic Read access is just the standard read permission, and includes "List folder / read data", "Read attributes", "Read extended attributes", and "Read permissions".) If you follow what happens with procmon, you will see that at the appropriate time, lsass.exe calls CreateFile to open the key file with Generic Read desired access.

    You do not need to restart the Remote Desktop Services service; it should pick up the changes the next time someone tries to connect. (However, you will need to restart the service if you want to disable access to the key.)

    Confirm your handiwork with certutil -store -v My. If you are using the legacy CryptoAPI, you should see "Allow Read  NT AUTHORITY\NETWORK SERVICE". If you are using the newer NCRYPT, you should see "Allow Write NT AUTHORITY\NETWORK SERVICE".

    This result requires some explanation. Instead of looking at the text summary, look at the SDDL instead. If you are using the legacy CryptoAPI store, the SDDL will likely include:
    (A;;GR;;;NS)

    GR is simply GENERIC_READ access, which is the access mask 0x80000000. So far, so good.

    But, if you are using the NCRYPT, you may get the following:
    (A;;0x80120089;;;NS)

    What is that? Well, it is actually "FR" plus "GR" in SDDL, aka FILE_GENERIC_READ plus GENERIC_READ. The certutil tool mistakenly calls this "Write", but it really is "Read".

    To compare, for your entries (such as SYSTEM) where the user has Full Control over the key in the file system, you get:
    Legacy CryptoAPI: (A;ID;GAGR;;;SY)  == GENERIC_ALL + GENERIC_READ
    NCRYPT: (A;;0xd01f01ff;;;SY)  == GENERIC_READ + GENERIC_WRITE + GENERIC_ALL + FILE_ALL_ACCESS

    Again, certutil botches it up and calls it "Write", when "Full Control" is probably the better descriptor. It appears that the NCRYPT system passes through the lower order bits of the actual file, while the legacy CryptoAPI does not.

    And there you have it: now you can use a custom certificate with Remote Desktop in Windows 7.

    • 回答の候補に設定 SeanTek 2009年9月12日 4:12
    2009年9月12日 4:12
  • SeanTek,

    Thanks, this advice was just was I was looking for - my Win7 PC is now presenting the desired certificate to remote users.

    But I'm not yet seeing the full desired behavior on the client-side, so I'll ask if anyone has found a fix:

    When I use my remote Win7 client to connect to my (Win 7 desktop) "myserver.domain.foo", it warns me that "The remote computer could not be authenticated due to problems with its security certificate." - the specific error is "The certificate is not from a trusted certifying authority". But I've added the (self-signed) cert to my Trusted Root Certification Authorities" store, and when I "View certificate" it actually shows as valid and trusted. For what it's worth, I"ve added it to the Local Computer\trusted root on the server itself since sometimes servers need to trust themselves for the client to authenticate.

    The CN of the certificate is identical to how I'm trying to connect to it, so it shouldn't be a mismatch there (the warning message even reiterates the CN and it is what it should be). I speculated that maybe I wasn't creating it with enough key usage attributes, so I created one for All Purposes but get the same error.

    I created it as follows:
    (First try with just the correct purpose)
    makecert -n "CN=myserver.domain.foo" -sk myserver -sr localmachine -ss my -pe -r -eku 1.3.6.1.5.5.7.3.1 myserver.cer
    (Second try with all purposes)
    makecert -n "CN=myserver.domain.foo" -sk myserver -sr localmachine -ss my -pe -r myserver.cer
    This is with the SDK 7.0 version of makecert.

    Any thoughts what else might be needed to get it fully trusted? I think I'm meeting the requirements outlined here for TS Remote Gateway, which I'd guess are the same:
    http://technet.microsoft.com/en-us/library/cc754252.aspx#BKMK_ObtainCertTSGateway

    Thanks
    • 編集済み Roger Wolfson 2009年11月14日 6:01 adding reference link
    2009年11月14日 5:48
  • Open regedit and go to the following key:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

    Create a REG_BINARY value with the name SSLCertificateSHA1Hash. Open it up, and enter the 20 bytes exactly as you saw it. This setting will tell Terminal Services (Remote Desktop Services) to use the SSL certificate identified by that SHA-1 hash.


    доброго дня!
    я сделал изменения в реестре и теперь у меня вообще не проверяется сертификат при удаленном доступе к windows 7
    2009年11月25日 9:23
  • все нашел решение...
    в локальной политике можно указать шаблон сертификата и вин7 сам будет выбирать сертификат из личного хранилища...
    параметр груп. политике "Server Auth Certificate Template"
    • 回答の候補に設定 kirimey 2009年12月15日 10:59
    2009年11月26日 4:45
  • Thanks, but that part is already working for me. The server presents my desired certificate, but the client program warns that the cert isn't trusted, even though the certificate properties show that it is.
    2009年11月27日 23:22
  • Open regedit and go to the following key:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

    Create a REG_BINARY value with the name SSLCertificateSHA1Hash. Open it up, and enter the 20 bytes exactly as you saw it. This setting will tell Terminal Services (Remote Desktop Services) to use the SSL certificate identified by that SHA-1 hash.

    I can't complete this process under Windows 7 - once I've created the key, it exists for a few minutes and then disappears !

    Whilst the key is inplace, the my Windows 7 machines does indeed present the correct Certificate to the client.

    I'm assuming something is deciding the key shouldn't be there, and removing it - although this seems rather odd, given that I manually put it there :)

    Any ideas ?
    2009年12月8日 16:51
  • @Nomgle
    If certificate hash disappears from the registry, it means there is something wrong with the certificate and in cannot be used for Remote Desktop authentication.
    Check system event log. It should tell you exactly what was wrong with the certificate.
    A valid certificate should not be expired, it shold have its private key and Enhanced Key Usage extension should contain "Server Authentication" attribute.

    Thx,
    Sergey.
    2010年1月14日 19:31
  • I tried to use these instructions to configure the RDP server in a Windows 7 Ultimate machine to use a certificate for SSL encryption. However, it didn't work and the client complained that the certificate was invalid.

    The certificate is a self-signed, generated using Microsoft's selfssl.exe using the following command line in a command prompt with Administrator privileges:

    selfssl /N:CN=91.123.224.28 /V:365

    Then I ran mmc.exe and added the Certificates snap-in for the local computer account. This new certificate showed up in the Personal subtree. I copied-and-pasted it to the "Trusted Root Certificates" subtree.

    I have previously done this for Windows Server 2008 R2, but using the tsconfig.msc GUI to accomplish the task here.

    Can anybody help?

    2010年6月25日 9:32
  • Great how-to for server side, thanks!

    One important note for the client side, if you use your own Root Certification Authority:

    Terminal services client requires the Root CA certificate to be stored in the Local machine store, along with its CRL (you will probably have to generate one even if you haven't revoked any certificates yet). If you don't import the CRL file, any connection attempt will end with an error message, saying that the certificate could not be verified (the reason is unknown, of course, is it really so difficult to add a few lines of code to at least display any HRESULT/reason/whatever???), despite the certificate view window says, that it is OK.

    PKCS12 certificate can be generated using openssl from the X.509 certificate and its private key using command:

    openssl pkcs12 -export -in cert.pem -inkey key.pem -out output.p12

    2010年7月30日 23:30
  • If there is a problem with the CRL lookup in a Windows 7 client attempting to connect to either a Windows 2008 R2 or Windows 7 machine using SSL/TLS and you get the message that you can't connect because the certificate could not be verified by CRL, the following entry in the Registry of the connecting computer will resolve the issue.  Once connected the CRL will be downloaded and updated automatically.  This entry tells the machine to use the Locally Cached CRL instead of the CRL on the CA.

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Credssp]
    "UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors"=dword:00000001

    Hope this helps.

    2010年9月28日 15:53
  • If there is a problem with the CRL lookup in a Windows 7 client attempting to connect to either a Windows 2008 R2 or Windows 7 machine using SSL/TLS and you get the message that you can't connect because the certificate could not be verified by CRL, the following entry in the Registry of the connecting computer will resolve the issue.  Once connected the CRL will be downloaded and updated automatically.  This entry tells the machine to use the Locally Cached CRL instead of the CRL on the CA.

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Credssp]
    "UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors"=dword:00000001

    Hope this helps.

    2010年9月28日 15:54
  • Worked perfectly on a Win2008 R2 standalone server in our DMZ.   This task has been on my ToDo's for a while, stellar explanation, thanks!
    2011年1月2日 9:52
  • I'm finally up and running, after putting this project on hold for a while !

    The key points for me were :

    1. I had to import my certificate into my Windows 7 server machine as a type .p12 certificate - this is the filetype that also includes the private key. Trying to import other filetypes (without the private key) resulted in Windows removing the registry key as in my other post. StartSSL have a web based tool that converts certs and their private keys into a single .p12 file.

    2. I did indeed have to adjust the permissions on the private key, allowing Read access to the Network Service account, as mentioned in SeanTek's instructions. Without doing this, my Windows 7 server didn't present any certificate at all to the client machines.

    3. As mentioned in Ladislav Havlat's post, I had to install my Root Certification Authority's (StartSSL) CRL certs into my client machines - they're available from https://www.startssl.com/certs/ca-bundle.pem - without doing this, I couldn't connect to the server and received an error message about being unable to check the CRL.

    4. You can grab a free "Webserver SSL/TLS Certificate" from http://www.startssl.com and it works just fine for this purpose.

    • 編集済み Nomgle 2011年2月7日 4:12 Edit.
    2011年2月7日 4:11
  • Thanks for this post. Everything works great and no more certificate warnings for my VDI guest VM's.

    However, do you know if there is anyway to automate this process through group policy? Adding the registry value and sha-1 hash can be done with a startup script, but I can't figure out how to add the Network Service account and give it Read permission for the private key.

    2011年5月11日 19:07
  • Refer to this blog entry for a relatively simple way to handle this:

    http://blogs.msdn.com/b/rds/archive/2010/04/09/configuring-remote-desktop-certificates.aspx

     

     

    2011年11月9日 20:21
  • Thank you, we were able to apply this setting in Windows 2008 R2 to resolve an issue when web access was with a domain that was different to the local domain. See http://social.technet.microsoft.com/Forums/sk/winserverTS/thread/4faa38f3-b86e-40cf-bc68-9f77d6ad760f.
    2012年6月7日 23:47
  • Hello SeanTek,

    Thanks a bunch!!!! for posting this information.

    I have literally been searching for weeks and weeks and found nothing but people posting similar issues like this, with no answer, i started to think this wasn't possible.

    I followed the steps and was able to specify the certificate i needed, :).

    I had to create an account just to mark this as helpful and reply, thanks again

    2017年5月10日 23:16