X509Enrollment.CX509PrivateKey Create without Admin rights

1

I'm writing a Powershell script that creates self signed certificates which works fine as an Administrator but fails as Admin:

The piece of code that fails when I call the Create method:

$PrivateKey = New-Object -ComObject X509Enrollment.CX509PrivateKey
$PrivateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
$PrivateKey.KeySpec = 0x1
$PrivateKey.Length = 2048

# set security descriptor
$PrivateKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"

# key will be stored in local machine certificate store
$PrivateKey.MachineContext = 0x1

# export will be allowed
$PrivateKey.ExportPolicy = 0x1
$PrivateKey.Create()

It throws this error:

Exception calling "Create" with "0" argument(s): "CertEnroll::CX509PrivateKey::Create: Access is denied. 0x80070005
(WIN32: 5)"
At C:\dev\LinoaSSC.ps1:106 char:1
+ $PrivateKey.Create()
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation

How should I troubleshoot or solve this error? Thanks guys!

powershell
x509certificate
asked on Stack Overflow Feb 19, 2013 by Swell

2 Answers

1

You need to be an administrator on the local machine to perform this and I believe most actions with certificates. I'm not aware of any acceptable methods to work around this, but there are ways to elevate your permissions.

answered on Stack Overflow Feb 19, 2013 by Christopher Douglas
-1

You can absolutely allow a non-admin to create machine key sets. You just need to allow the account you would like to create private keys to have write permissions to the following default directories.

C:\ProgramData\Microsoft\Crypto\Keys
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates
C:\ProgramData\Microsoft\Crypto\RSA

Then, in your code, provide a SecurityDescriptor on the CX509PrivateKey object before calling the Create method. The default SD is "D:P(A;;0xd01f01ff;;;CO)(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)", but simply add an entry for the account SID.

Curiously, the SecuityDescriptor does allow “CO”, which means CreatorOwner, but for CNG certificates, the private key gets created by lsass.exe running as SYSTEM, which is impersonating the account that requests the certificate. By default, this doesn’t allow the account that requested the certificate for some reason. It does appear that with CryptoAPI certs, the CreatorOwner SecurityDescriptor does allow the requesting account with the default SecurityDescriptor.

Note: carefully consider the security implications for your environment. This will allow the account to have access to the private keys in the machine store. In my scenario, principal of least privilege was a better trade off than granting the account full admin privileges.

answered on Stack Overflow Sep 29, 2018 by Cory Murphy • edited Oct 1, 2018 by Cory Murphy

User contributions licensed under CC BY-SA 3.0