I have a .crt and .key file, from which I am creating a .pfx file using OpenSSL. I am trying to use PowerShell to import the .pfx file into Cert:\LocalMachine\My, then I'll use that certificate for OpenVPN. Using the following code, I am not getting any errors on the import:
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.import("$env:TEMP\$site.pfx", $certPassword, "PersistKeySet")
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My", "LocalMachine")
$store.open("MaxAllowed")
$store.add($cert)
$store.close()
I can see the cert in the MMC, but OpenVPN's log file shows:
error:C5066064:microsoft cryptoapi:CryptAcquireCertificatePrivateKey:Keyset does not exist
I have tried $certPassword as both a string and secure string. When I import the certificate via the GUI (copying the password from the content of $certPassword), OpenVPN starts normally.
I also tried this code but saw the same behavior:
Import-PfxCertificate -Password ($certPassword | ConvertTo-SecureString -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\My -FilePath $env:temp\$site.pfx
Finally, I am running the PowerShell session elevated.
What could I be doing wrong? Thanks.
Since you are adding the certificate to the LocalMachine\My store you probably want to import it with X509KeyStorageFlags.MachineKeySet
That might be
$cert.import("$env:TEMP\$site.pfx", $certPassword, "PersistKeySet | MachineKeySet")
but I don't actually know PowerShell, so I don't know the flags syntax.
The second possibility is that the PFX import saved the key under CNG but OpenVPN didn't use the "I know what CNG means" flag. You can make the import load the key in CAPI by specifying the CSP value when building the PFX with openssl
openssl pkcs12 -export ... -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider"
Related
I have configured a powershell script, which creates a vpn conection profile.
To make it work i need to add proper certificate.
Everything works fine when i add a certificate manually to local machine:
More detailed regarding importing certificate manualy:
Info
I'm trying to perform this task via powershell, but it doesn't work (script seems to work, but i am not sure to which stores should i copy certificate). In contrary to manual method - the certificate added by my powershell script is invisible for vpn connection.
#add certificate
$cert_name=$env:USERNAME+"#vpn.contoso.com.p12"
$cert_loc="\\ad\deploy\other\certs\"+$cert_name
$secure_pwd = ConvertTo-SecureString "contoso987%#" -AsPlainText -Force
Import-PfxCertificate -FilePath $cert_loc -CertStoreLocation Cert:\LocalMachine\My -Password $secure_pwd
# Add vpn connection
Add-VpnConnection -Name "Example VPNX" -ServerAddress "vpn.example.com" -AuthenticationMethod "MachineCertificate" -TunnelType "IKEv2" -EncryptionLevel "Maximum" -SplitTunneling $True
I would like to do it the same way the certificate import wizard does. Does anyone have experience in that ?
PS
I've changed addresses in codes etc.
Kind Regards,
Tamara
I've decided to post the solution. Although it is not developed in powershell it solves the problem completely. It is possible to import these kind of certificates from command prompt:
certutil -f -p Some_password -importpfx "\\ad\somepath\certificate.p12"
I am trying to install a certificate provided by mitmproxy.org via powershell and windows is not saving the certificate in the correct location.
Commands I tried to run:
Get-ChildItem -Path c:\mitmproxy-ca-cert.p12 | Import-PfxCertificate -CertStoreLocation cert:\LocalMachine\Root Instead of inserting a cert into Trusted Root Certification Authorities, it put it in Intermediate Certification Authorities.
Get-ChildItem -Path c:\mitmproxy-ca-cert.p12 | Import-PfxCertificate -CertStoreLocation cert:\CurrentUser\Root Did the same as the first command.
Even setting the working location to PS Cert:\localmachine\Root> did not manage to import into the Root location. Get-ChildItem -Path c:\mitmproxy-ca-cert.p12 | Import-PfxCertificate -CertStoreLocation .
There are no errors, all commands ran their course. I ran them with admin privileges.
Manually left-clicking on the mitmproxy-ca-cert.p12 however does start an import GUI that successfully imports it into the Root location. Why is the powershell not working tho?
Following mitmproxy.org own guide for command-line installation is of no use because it simply doesn't work:
How to install on Windows (Automated)
certutil.exe -importpfx Root mitmproxy-ca-cert.p12
C:\>certutil -importpfx Root mitmproxy-ca-cert.p12
Enter PFX password:
CertUtil: -importPFX command FAILED: 0x80092007 (-2146885625 CRYPT_E_SELF_SIGNED)
CertUtil: The specified certificate is self signed.
Can anyone shed some light what is going on here? Thank you.
I make a script for you, tell me if you don't understand.
$in_cert = "C:\Users\Marian\Desktop\Pfx Certificate.pfx";
$password = Read-Host -AsSecureString;
# Read the pfx certificate data:
$pfx = (Get-PfxData -FilePath $in_cert -Password $password -ErrorAction Stop);
# Get the root and publisher certificate:
$root = $pfx.OtherCertificates[0];
$publisher = $pfx.EndEntityCertificates[0];
# Add the root:
$rootStore = Get-Item "Cert:\CurrentUser\Root";
$rootStore.Open('ReadWrite');
$rootStore.add($root);
$rootStore.close();
# Add the publisher:
$rootStore = Get-Item "Cert:\CurrentUser\TrustedPublisher";
$rootStore.Open('ReadWrite');
$rootStore.add($publisher);
$rootStore.close();
Pause;
I posted to my post too: My Post
p12 file with 7 certificates in it.
Following the instruction that came along with the cert file, we have to use MMC and a password to import all certs into a personal store.Instruction also says to check mark private key exportable.
in order to automate this, I tried using certutil -importpfx but that only added 4 out of 7 certificates. I am unable to see other 3 certs. The diff i noticed is the imported certs are the ones with "ext issuing CA" and missing certs are with "issuing CA" in the Subject .
Any pointers please
I found an alternate solution using powershell instead of certutil .
Import-pfx with flag -exportable imported all the certs.
Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\My -Password $Securepwd -FilePath $findP12Cert.FullName -Exportable -Verbose
PowerShell 4.0
makecert tool has the -eku option for describing the enhanced key usage object identifiers (OIDs) into the certificate. It allows to make the certificates for code signing and for other purposes. But it is not a cmdlet.
New PowerShell versions have the New-SelfSignedCertificate cmdlet for local testing of the scripts. But it creates the certificate that can't be used for code signing:
New-SelfSignedCertificate -DnsName www.SomeSite.com -CertStoreLocation Cert:\CurrentUser\My
I don't see an option which is similar of -eku.
How can I set the destination of my new Self-Signed Certificate (created through New-SelfSignedCertificate cmdlet) for possibility of its use for code signing? Or is it possible to do the same via other cmdlet?
The version of New-SelfSignedCertificate on PS 4 is rather basic.
However Powershell v5 has the parameters that you would require to create specific keys.
Specifically a Keyusage parameter that takes
-- CertSign
-- CRLSign
-- DataEncipherment
-- DecipherOnly
-- DigitalSiganture
-- EncipherOnly
-- KeyAgreement
-- KeyEncipherment
-- None (default)
-- NonRepudiation
and a KeyUsageProperty taking
-- All
-- Decrypt
-- KeyAgreement
-- None (default)
-- Sign
Are you specifically tied to v4? If you can upgrade to v5 you should be able to achieve what you need.
Reviving this question as I was also looking for an answer to set Enhanced Key Usage (EKU) field for code signing using PowerShell New-SelfSignedCertificate command.
It can be done using the -TextExtension parameter to set EKU value. As an example, the following PowerShell (tested on PowerShell 5.1) script allows to create a 3-years self signed code signing certificate with extended key usage (and export it from the current user's certificates store to pfx file format):
# Enhanced Key Usage
$EKU = "2.5.29.37"
$EKU_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"
$certificate = New-SelfSignedCertificate -Subject "CN=Testing Code Signing,E=info#mycompany.com,O=My Company" `
-FriendlyName "My Code Signing Certificate" `
-NotAfter (Get-Date).AddYears(3) `
-CertStoreLocation Cert:\CurrentUser\My `
-TextExtension #("$EKU={text}$EKU_CODE_SIGNING")
$password = ConvertTo-SecureString -String "mypassword" -Force -AsPlainText
Export-PfxCertificate -Cert "Cert:\CurrentUser\My\$($certificate.Thumbprint)" -FilePath "codesigning.pfx" -Password $password
Note: As a shortcut, the -Type CodeSigningCert parameter can be specified with the New-SelfSignedCertificate command instead of explicitly adding the EKU_CODE_SIGNING string to the -TextExtension parameter.
You can use PS' cert provider to access different cert stores (user vs machine), but that won't help with your OID problem. I suggest you look at .NET support for X509 certs. Google ".net x509 certificate" and you'll find the X509Certificate class on MSDN. From there read the class documentation and any overview documentation to see if creation of OIDs is supported. If .NET doesn't support it then you'd have to use P/Invoke to invoke native Windows CNG (cryptography next generation) APIs
I am trying to export a certificate public and private key to a PFX file via a powershell script. I am currently using the following code
Get-ChildItem -Path Cert:\CurrentUser\My\$Thumbprint | Export-PfxCertificate -FilePath $OutputFile -Password $privateKeyPass -ChainOption EndEntityCertOnly
However, when I work with the resulting PFX file in something like certutil, it doesn't ask for a private key password. For example here is an example of what I get when i dump the cert with certutil:
> certutil -dump cert.pfx
Certificates: Not Encrypted
================ Certificate 0 ================
[cert data removed]
---------------- End Nesting Level 1 ----------------
Key Container = PfxContainer
Provider = PfxProvider
Encryption test FAILED
CertUtil: -dump command completed successfully.
If I use the certificates MMC snapin to export the cert I can select the "Enable certificate privacy" option and it will export an encrypted certificate.
My question is...
Is there a way to tell the export-pfxcertificate cmdlet to enable certificate privacy so that it is encypted? If not, what other solution do I have?