CertUtil Import pfx failed: NTE_NOT_SUPPORTED - sql

I am attempting to set the KeySpec flag on an existing certificate for use in a SQL server encryption role. Current KeySpec is 0, and I need it to be a 1.
The way to do this is by first exporting the cert, its private key, and key usages into a .pfx file (with a password, regardless of what it claims). Then, utilizing certutil, run certutil -importpfx AT_KEYEXCHANGE.
This "works" in that it prompts for the password (which is typed in correctly), but it fails with this error message:
CertUtil: -importPFX command FAILED: 0x80090029 (-2146893783 NTE_NOT_SUPPORTED)
CertUtil: The requested operation is not supported.
Unfortunately, there's not much online that I could find - just this one post apparently:
https://anotherexchangeblog.wordpress.com/tag/importpfx-command-failed-0x80090029/
That one appears to indicate that it's a problem with permissions on a directory located at C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. Specifically, that "SYSTEM" had permissions on it, which he removed and got certutil working. However, my copy of that directory does not have SYSTEM with permissions - it looks to be the same as his picture.
Not a whole lot more to go on, and this certutil import method appears to be the only way to set KeySpec to 1. What can I do from here to allow me to import that key with the correct KeySpec flag?

I encountered this issue after generating my private key with Template = (No Template) CNG Key
To convert from CNG key back to Legacy Key you can use OpenSSL (https://www.google.com/search?q=Download+windows+OpenSSL) to re-encode the certificate
Export your current certificate to a passwordless pem
openssl pkcs12 -in mycert.pfx -out tmpmycert.pem -nodes
Convert the pem file to a new pfx file with password:
openssl pkcs12 -export -out mycert2.pfx -in tmpmycert.pem
You can avoid the problem by generating your CSR using Template = (No Template) Legacy Key
Good Luck!

I work at Microsoft. My customer got this today and we couldn't fix it. We ended up making a new CSR.
This is the main article that explains how key specs work and CNG versus a legacy Cryptographic Service Provider.
https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/technical-reference/ad-fs-and-keyspec-property
What you can do is go to your MMC snap in for certificates. Right click on the personal store -> All tasks -> Advanced Operations -> Create custom request.
Proceed without an enrollment policy -> select Legacy template, -> PKCS #10 -> Next -> DETAILS -> Properties
Put a friendly name -> Add a common name -> Add a DNS names for any SANs you need-> on Extended Key Usuage select Server and Client Authentication -> on the Private Key Tab -> select Microsoft Strong Cryptographic Provider -> for Key Options you want 2048 -> Make the private key exportable -> Key Type tab -> select Exchange
This will generate a (CSR) Certificate Signing Request and then have your Certificate of Authority full fill it.

It is possible to make certutil import use the legacy Strong Cryptographic Provider by specifying the -csp argument.
certutil -csp "Microsoft Strong Cryptographic Provider" -importpfx -f -enterprise my mycert.pfx AT_KEYEXCHANGE

Related

How to create a .pfx certificate from a .cer whitout the private key?

I would like to import an SSL certificate on an Microsoft Azure Website.
I generated the .csr request file using the windows command "certreq" direclty on mylaptop (not on the server).
I retrieved an CER certificate using this .csr file.
But know I'm blocked, the Azure websites page wants a .pfx file and refuse the .cer file.
I tried to use www.sslshopper.com to transform my .cer certificate into a .pfx file but it needs the private key...
So Here are my questions :
* Can I transform a .cer to .pfx without a the private key ?
* how can I get the private key used by the certreq command of my laptop ?
Thanks !
As I known, certreq would store your private keys in your certificate store when it generates CSRs. And you need to finish the certificate request on the same computer where you generated the CSR request. There is issue about finding the private key after using certreq for CSR generation.
Based on your description, you could follow this tutorial to import your signed certificate into the windows local computer certificate store by using certreq, then click "Start > Run", type certmgr.msc to manage computer certificates, right click the certificate root node and choose "Find Certificates" to find your certificate as follows:
Click export your certificate, choose the option "export the private key", then export your certificate to .pfx file. Also, you could leverage DigiCertUtil to export your certificates.
Additionally, for more flexibility over your private key than certreq, you could use OpenSSL command line tool to generate your private keys and your certificate signing request instead of certreq. Also, for a simple way, you could use this GUI tool startcomtool to generate your CSR and export the certificates.
You need to associate private key with issued certificate. Depending on context used in certreq (current user or local machine context) run appropriate command:
certreq -user -accept path\certfile.cer
Or
certreq -accept path\certfile.cer

Security Certificates

I've currently encountered a unique issue. To help understand the predicament I'll provide some background. Our company hired a third-party to develop an application, apart of this web application package was the purchase of an SSL Certificate.
After they purchased the SSL they exported it into a Personal Information Exchange (.pfx).
The issue now occurs here...
Our company web-server utilizes the Plesk Panel 11. Which complicates matters for two reasons.
The first is that if I directly install the certificate Plesk will
not recgonize the certificate and will eventually overwrite the
contents in our Microsoft Certificate Store within the Windows
Server MMC Certificate Snap-In.
The second issue is sheer bad luck, Plesk doesn't recognize the .pfx extension. It apparently only understands the following:
Private Key (.key)
Certificate (.crt)
CA Certificate (-ca.crt)
So my original thought was to simply convert the file into a valid format, which resulted in an error. The second attempt was to follow a command line control to export the file format to the valid extension. The results are still disappointing:
Error: Invalid Certificate Format
Since the file installed was a .pfx it does not allow me to convert it to anything else. Unfortunately when utilizing Open SSL it only converted to a .pem. Which to my dismay is also unsupported-
Any assistance would be terrific.
Update:
I attempted to follow this question on Stack Overflow. Unfortunately Windows Server 2012 doesn't appear to do the conversion as well. It does convert it into a valid format, but then the Private Key can't be found.
In order to solve this issue I followed this blog here.
So I attempted to utilize Open SSL again, with these steps:
// Extract Private Key
openssl pkcs12 -in [yourfile.pfx] -nocerts -out [keyfile-encrypted.key]
// Extract Certificate
openssl pkcs12 -in [yourfile.pfx] -clcerts -nokeys -out [certificate.crt]
// Encrypted Private Key
openssl rsa -in [keyfile-encrypted.key] -out [keyfile-decrypted.key]
Again you need to enter an import password. This time you need to enter the new password that you created in step 1. After that you’re done. You decrypted your private key. In the folder you ran OpenSSL from you’ll find the certifcate (.crt) and the two private keys (encrypted and unencrypted).
That is how I solved my question.

No private key in SSL Certificate for IIS 6.0

We use IIS 6.0 (Win2003 SP2) at work and needed to renew our SSL certificate.
I created a certificate request by using openssl. Therefor I'd created a 2048 bit key with openssl first. I did not use that certreq.txt request file, since that produced format errors at the website of our used CA.
That request has been accepted meanwhile and I got a .pem file from our organization's CA. So far so good. I even was able to import the certificate. But unfortunately the private key is missing now. I think, windows (or IIS) just doesn't know, where to look for it. The private key of course lives in a *.key file, that I used for creating the request.
But how may I integrate the key into the certificate or make Windows/IIS using it?
You should be able to build a PKCS#12 file using OpenSSL using:
openssl pkcs12 -export -in cert.pem -inkey file.key -out cert.p12
Then, using the .p12 file, import both the cert and its private key at the same time.
More info on openssl https://www.openssl.org/docs/apps/pkcs12.html
Since your running Windows Server take advantage of DigiCert's free utility (http://www.digicert.com/util).
You can create the CSR from OpenSSL if you plan to import it back to OpenSSL and were using Apache.
Otherwise you'll make the CSR request from IIS or running DigiCert Utility and clicking 'Create CSR' option. Once you have the new CSR, submit it to your CA in order to have them issue a new cert that will match the proper private key in IIS.
Once you receive the new cert file, use the 'Import' function on the utility to load the cert file on your local MMC.
Final step is binding the SSL cert to the site's port 443 connection in the IIS console.
If you happen to need the private key, you can use the 'Export' function to create a .key file or a PFX file which includes both your domain certificate and the private key.
Some firewall devices require a PKCS#12 file over the PFX. If so, rename file extension from .pfx to .p12

Unable to use libcurl to access a site requiring client authentication

I’m using the below snipped for setting the certificate and key for client authentication.
curl_easy_setopt(curl,CURLOPT_SSLCERT,"clientCert.pem");
curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEY,"privateKey.pem");
curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");
The certificate doesn’t have a password, I don’t know why on earth the option SSLCERTPASSWD exists, I just provided a dummy value.
When I run the program on Linux I get an error code of 58 and an error message
unable to set private key file: 'privateKey.pem' type PEM
On Windows however I get
unable to use client certificate (no key found or wrong pass phrase?)
It seems to suggest the certificate and the key don’t match but I don’t know how. I have extracted both the cert and the key from a p12 file using openssl commands.
The command I used to extract the key is
openssl.exe pkcs12 -in client.p12 -nocerts -out privateKey.pem
and the command used to extract the cert is
openssl.exe pkcs12 -in client.p12 -nokeys -out clientCert.pem
The p12 file has been successfully used in a browser to access the client authentication url.
Please help before I shoot myself.
Edit:
Here is proof that the private key and the certificate correspond to each other:
[debugbld#nagara ~/curlm]$ openssl x509 -noout -modulus -in clientCert.pem | openssl md5
d7207cf82b771251471672dd54c59927
[debugbld#nagara ~/curlm]$ openssl rsa -noout -modulus -in privateKey.pem | openssl md5
Enter pass phrase for privateKey.pem:
d7207cf82b771251471672dd54c59927
So why can’t it work?
Using the command line curl, I've got the same error using a .pem file that was also obtained with openssl from a p12 file, The p12 was also able to working properly doing client authentication when imported in a browser. Just like you described, I think.
My problem was caused because the .pem file was not listing the certificates in the proper order: seems that each certificate in the file has to be followed by its issuer certificate. I edited the file and changed the order of the sections and curl was happy.
For the record, my original .p12 file was obtained by backing up a certificate from Firefox.
Also note that in my case, I was not getting prompted for the password and was getting the
curl: (58) unable to set private key file: 'alice.pem' type PEM
before the password prompt
I was facing similar issues, I found out the problem was related to file permissions of the certificate and private key files. The process running PHP did not have read access to those files.
One thing you can try (and that helped me figuring this out) is to run the following code:
$result=openssl_get_privatekey('file://path/to/private/key.pem','password');
and check if the returned value is not false and there are no errors. I was getting:
file_get_contents(/path/to/private/key.pem): failed to open stream: Permission denied
Thanks Hugh for the thread and raugfer for the openssl hint. The later: both helpful and misleading. ;-)
Actually, I solved the problem by making sure that the path of the key file is correct. And here is why the openssl hint was misleading, dispite helping me to check if my PEM file was ok:
cURL needs the complete path, but without 'file://' prefix. While fopen is happy with a relative path, cURL is not. So, all my tests to open the key file had been successful, while cURL was not.
Btw.:
curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");
are not needed, as the password is only used to decrypt the private key and PEM is the default.

how to use X509 certificates (to sign a file w/ simple verification, + other questions)

I spent several hours yesterday trying to digitally sign a short file using an X509 certificate (one of the "freemail" certificates from thawte). I finally got openssl to sign it as an SMIME message, but I can't successfully verify it, AND it's in the SMIME format -- I don't have access to a "sendmail" program which can actually send out the SMIME file.
I just want to create some file that is "excerptable" via plain cut & paste, like:
===BEGIN SIGNED DOCUMENT===
===BEGIN DOCUMENT===
blah blah blah this is the plaintext ...
===END DOCUMENT===
===BEGIN SIGNATURE===
AFab12121abadAF ...
===END SIGNATURE===
===END SIGNED DOCUMENT===
Alternatively I guess I could make a .zip file that contains the original file and also the signature.
so I guess my requirements are:
input plaintext = arbitrary file
input signkey = from X509 certificate
output = something I can easily email to someone else by cut&paste or by attaching a single .zip file
program = something that is free & open source like openssl or gpg
program != a magic GUI where I don't understand what's going on
ability to easily use the program to generate output from inputs
ability to easily extract the plaintext from the output (e.g. either directly by eye or as a component of the .zip file)
ability to verify that the plaintext was signed by the grantee of the X509 certificate (i.e. me) and that the grantor (CA) of the certificate is a Well-Known CA... assuming that I am a rational person who keeps the certificate secure from use by other parties (otherwise someone could sign things as me).
Is there a good tutorial for X509 certificates & how they are used in practice for this stuff? I have the 2nd edition of Schneier's "Applied Cryptography" & have a fair amount of experience with cryptographic algorithms + protocols, but don't know much at all about X509 and I'm really confused as to what a certificate actually is in practical terms. (In other words, "a certificate is a cryptographic assertion by the issuing party CA that the party X named in the certificate is an identity known to the CA?" AND "a certificate enables its bearer to _____")
When I get one it shows up in Firefox's "Your Certificates" tab of the Certificate Manager, and I can export it and read it with openssl, but I want to make sure that it's not stored in any way that someone else can use it w/o knowing the cert. passphrase -- and I get really confused because it seems like some certificates only have the public key & others have encrypted private keys.
Is there a good, simple GUI wrapper around openssl that allows you to have it explain what it's doing?
edit: thawte doesn't easily let you use certificate requests directly; instead it talks to web browsers (I use Firefox) & that generatese the private key and handles all the certificate protocol. So I can export that as a PKCS12 file but am not exactly sure how to use that.
So I can export that as a PKCS12 file but am not exactly sure how to use that.
If you use the openssl tool, you can use the command
openssl pkcs12 -in file.p12 -out file.pem
to convert it to pem-format.
EDIT:
I'm having trouble figuring out what PEM and PKCS12 and all these things do differently from each other
A PKCS#12 file is just a container for certificates and keys. If you want to see what it contains (at least except for the encrypted parts), you can use a tool such as dumpasn1. The PKCS#12 file that you export from your browser will contain your private key in an encrypted format, your certificate as well as the CA certificates that are necessary to form a chain up to a trusted CA.
Likewise a PEM file can contain certificates and keys. In a PEM file the certificates and keys are base64 encoded and placed within some text delimiters (a PKCS#12 file uses a binary encoding named ASN.1 to structure the file - you can think of ASN.1 as a binary form of XML. Most cryptographic structures you encounter will have been encoded using ASN.1). Except for that, the only real difference between the formats is that PKCS#12 contains an integrity check - otherwise the formats are equivalent.
OpenSSL works best with PEM, while most browsers and emailapplications will expect PKCS#12, but you can freely convert between the formats.
First you probably need to read up on the difference between a private key, a public key and a certificate. A certificate is a signature with a CAs private key on the statement "The public key XX belongs to the person YY". If you sign something with your private key, the signature can be validated with your public key, and a third party that trusts the CA can conclude that the signature was signed by you.
If you generate a S/MIME message and attach it as a file with the extension .p7s, most mail programs will probably be able to verify it.
If you want total control over what you are doing, my experience is that the tooling around the PGP-format gives you better control (compared to the mail-programs implementing the S/MIME protocol).