简体   繁体   中英

Grant security to a private key in Windows Server 2012 via powershell w/out external DLLs, etc

I'm trying to figure out how to grant security to a private key in Windows Server 2012 via powershell (v5).

I've got an SSL certificate from LetsEncrypt, and need to use it for my email server, which relies on it being in the certificate store. I can successfully add the cert, but can't quite figure out how to grant security to the private key. Of course, doing manually via GUIs everything works fine, but I want to automate using powershell scripts so renewal is lights-out easy.

With a PS command I can list the cert, using name or thumbprint, but I can't figure out how to tie it to the cert key file stored in the "C:\\ProgramData\\Microsoft\\Crypto\\Keys" folder. This locaiton seems to hold the actual keys and supposedly granting security to my service's user will allow it to work (I checked the files in that directory, and the random name that has the correct create-date is the one my service user does have read access for, I just can't figure out how to automatically link the random GUID file name to my desired cert).

A number of different options ( link1, link2, link3 ) I've seen while researching don't work - they seem to rely on something in the "PrivateKey" attribute. I'm working directly with the private key so the "PrivateKey" attribute is seeminly blank (or at least does nothing when I try accessing it.

I'm newish to configuration with windows certs, I'm better in *nix where it's just cert files you reference in your config files.

PS C:\\> ls Cert:localmachine\\my | WHERE {$_.thumbprint -eq 'XXXXXXX_THUMBPRINT_XXXXXXXXXXXXXXXXXXX95'} | Format-list *

PSPath                   : Microsoft.PowerShell.Security\Certificate::localmachine\my\XXXXXXX_THUMBPRINT_XXXXXXXXXXXXXXXXXXX95
PSParentPath             : Microsoft.PowerShell.Security\Certificate::localmachine\my
PSChildName              : XXXXXXX_THUMBPRINT_XXXXXXXXXXXXXXXXXXX95
PSDrive                  : Cert
PSProvider               : Microsoft.PowerShell.Security\Certificate
PSIsContainer            : False
EnhancedKeyUsageList     : {Server Authentication (1.3.6.1.5.5.7.3.1), Client Authentication (1.3.6.1.5.5.7.3.2)}
DnsNameList              : {www.mydomain.com, mydomain.com}
SendAsTrustedIssuer      : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId                 :
Archived                 : False
Extensions               : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid...}
FriendlyName             :
IssuerName               : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter                 : 6/11/2017 1:45:00 PM
NotBefore                : 3/13/2017 1:45:00 PM
HasPrivateKey            : True
PrivateKey               :
PublicKey                : System.Security.Cryptography.X509Certificates.PublicKey
RawData                  : {44, 444, 4, 44...}
SerialNumber             : 03XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SubjectName              : System.Security.Cryptography.X509Certificates.X500DistinguishedName
SignatureAlgorithm       : System.Security.Cryptography.Oid
Thumbprint               : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX95
Version                  : 3
Handle                   : 4XXXXXXXXXXX
Issuer                   : CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Subject                  : CN=mydomain.com

None of the info/thumbprints/etc in that certificate info matches private key files listed here:

PS C:\\> ls C:\\ProgramData\\Microsoft\\Crypto\\Keys

Directory: C:\ProgramData\Microsoft\Crypto\Keys

Mode   LastWriteTime      Length Name
----   -------------      ------ ----
-a--s- 3/13/2017 6:00 PM  2369 20XXXXXXXXXXXXXXXXXXXXXXXXXXXXXd_7cXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX73
-a--s- 3/13/2017 1:45 PM  2369 59XXXXXXXXXXXXXXXXXXXXXXXXXXXXXb_7cXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX73
-a--s- 3/13/2017 5:14 PM  2369 7fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXa_7cXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX73
-a--s- 2/10/2017 3:24 PM  2369 c0XXXXXXXXXXXXXXXXXXXXXXXXXXXXX0_7cXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX73

I don't know if this is the official way or a total hack..But this is what I did.

$Certificate = new-object 
System.Security.Cryptography.X509Certificates.X509Certificate2
$Certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
$PKeyPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" + $PKeyFile
Set-FilePermissions -File $PKeyPath -Rights @($Rights) -AllowDeny 'Allow' -
Account $Account -AddRemove 'Add'

All you need to supply is the $Account and $PKeyFile.

Here's how to find the private key in the file system when the certificate thumbprint is known.

Get-ChildItem Cert:\LocalMachine\My\ | WHERE {$_.thumbprint -eq 'XXXX_thumbprint_XXXX'} | %{$_.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName}

The output is the filename for the key, typically in the MachineKeys folder (eg C:\\ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM