How to retrieve the private key of a user certificate? - windows

I want to retrieve the private key of a user certificate under Windows.
I use the CertOpenSystemStore and CertEnumCertificatesInStore methods to retrieve the user certificate.
Then the CryptAcquireCertificatePrivateKey method to retrieve the private key but there is a problem with the access rights.
Is this the right way to proceed?

The Certificate of a User Account is not stored in the 'Computer Store', if you need permissions on a key stored in the Computer store, you need to:
run certlm.msc
navigate to the certificate
right click > 'all Tasks' > 'Manage Private Keys ...'
set your desired permissions
If the certificate is in a user store, you must impersonate that user and access its personal store. In this case, you can export the key if the key is marked as exportable.
If the key is generated by a PKI, there is also the possibility that the key is available at the PKI but this depends strong on the configuration of the PKI

Related

Developer ID Application Certificate missing a child key in Keychain Access

I am trying to recreate a Developer ID Application certificate, so I can sign my application. I had an existing certificate, but it's about to expire, so I am trying to regenerate a new one.
However, when I download a newly generated certificate from developer.apple.com, the imported certificate has no key as its child node in Keychain Access. The old certificate had this. When I attempt to use the certificate for code signing I receive something like:
/tmp/myapp.app/Contents/app/bin/myapp.exe: errSecInternalComponent
I am following the instructions to obtain a signed certificate using Certificate Assistant:
Ensuring nothing is selected in Keychain Access, click Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
I enter my email, accept the default Common Name and click Saved to disk.
In developer.apple.com I click the "+" to Create a New Certificate
I choose Developer ID Application
I upload the CSR I saved above
I download the .cer file that is generated
I open the .cer file. This adds the certificate.
As you can see, the certificate does not have a private key inside it, like the old one:
Unfortunately I don't have the old certificate now having deleted it in a fit of pique but it looked like this:
... although in my case it had my private key.
I've noticed reference to the claim that creating a CSR also creates a public/private key pair, but I cannot see these anywhere in Keychain Access.
Later, I did manage to import the certificate and it show the private key. I think this was when I imported it into the same keychain as that which contains a private key "Dan Gravell" - login. However, I have since tried replicating that and now the certificate is being imported without a key again.
Xcode appearance
I've discovered there's a little more information in Xcode. The certificate shows "Missing Private Key" next to it:
When I look this error up, the suggestions seem to be that the certificate has been given to a developer by some third party that didn't include the private key. However, in my case I am that third party who has created the CSR and received the certificate originally and I thought I had the private key, otherwise I wouldn't have been able to create the CSR in the first place. All these items appear to be in my keychain.
I (eventually) got a reply from Developer Program Support. They issued a new certificate which I installed via XCode this time. I documented my other steps here: https://stackoverflow.com/a/74210449/28190

Detect the existence of a private key

I 'm trying to present the user a dialog to pick a certificate. Originally I used CryptUIDlgSelectCertificateFromStore with the "MY" store, but this results in picking all the certificates, where I only want the user to select between the
certificates that have private keys.
For that reason, I create a new memory store and store only the certificates for which a private key exists. I can use CryptAcquireCertificatePrivateKey to get a private key of a certificate, but this may result in a dialog box requesting a PIN for example. I don't want to use the CRYPT_ACQUIRE_SILENT_FLAG because a provider might want to show information on the key (not necessarily a pin or a smart card prompt).
Is there a way to know that there is a private key without actually acquiring it?
Thanks.

no certificate available when enrolling on behalf

I have one WinServer 2008 Domain controller and a CA server on it.
I log in with the Administrator account and want to request a certificate "on behalf" of a user of my DC.
for doing that, at first I duplicated these certificate templates:
smart login
smart user
enrolment agent
I changed configuration and permission for new templates so that Administrator account can read, write and enrol for these templates.
After creating these new templates and assigning permissions and configuration, from mmc and certificate snap-in, for user account certificates, and for "Personal" section, we requested a new certificate for Administrator account to make it an enrollment agent as shown below:
then it is generated with no problem and we want to request a certificate on behalf of a user with this new certificate. But, in "Select enrolment agent certificate" and when we click on "Browse" button, we have a problem because there is no certificate to select, as shown below:
there is no certificate available to choose
I read a lot of documents online but I did not find the reason to solve this problem!
You need an enrollment agent certificate in the local user store (certmgr.msc)/machine store (certlm.msc) to request on behalf of. This is done by setting the signature count on the template.
If the signature count is not 0 you cannot enroll - because you first need an enrollment agent certificate...
Set the signature count on the enrollment agent certificate template to 0.
Enroll an enrollment agent certificate - dialog will not pop up
Set the signature count on another certificate template to 1.
Enroll a certificate based on the template in step 3. Dialog will pop up. Select certificate enrolled in step 2. Done
I have same problem too (cannot choose existing enrollment cert).
The solution (maybe):
Check the access to published crl and/or refresh the crl cache on your enrollment workstation.
From elevated command line:
Delete the old cache: certutil -urlcache crl delete
Resync the crl cache: certutil -setreg chain\ChainCacheResyncFiletime #now

MMC console - certificate private key handling

We have an application that needs to access the private key of a certificate. We also have have a Nightlybuild that sets the certificate up (imports it from a pfx file using certmgr). This works really fine as long as the setup of the certificate and the access of the certificate runs under the same logged in Windows user (Windows7).
Now, we would like to introduce a test (that is executed during the Nightlybuild automatically) where another user will invoke the program that needs to access the private key of the certificate and I am struggling with the MMC console -> All Tasks -> Manage Private Keys.
For me it looks like I can change anything in the security settings of "Manage Private keys", but it does not have anything to do with the real ACLs of the certificate. I could reduce the problem to the following manual steps:
User1 imports the certificate into "Local Computer/My" (correct CA in root exists)
User1 selects the certificate in MMC, clicks on "Manage Private Keys" and adds "Users" (group) and "User2" (user) with Full Control permissions.
User1 logs out
User2 logs in
User2 opens MMC, clicks on "Manage Private Keys" --> Error, the MMC console displays "Cannot find the certificate and private key for decryption."
Although User2 should have access to the private key. So it seems to me that the settings of User1 (both, User1 and User2 are in the Administrators group) in MMC have no meaning whatsoever and are ignored by the .NET API that accesses the private key?
Does anybody have any idea why this is so and how I can try to persuade Windows that we really want two users to be able to read the private key of a certificate?
Thanks for any help
Michael
I just ran into this same issue. I was trying to use a code signing certificate as a user that did not import the certificate on the system. When the certificate was originally imported, it was not imported so that the private keys could be exported.
I was able to fix our issue by:
Deleting the existing certificate from the certificate store
Importing the certificate again while making sure it allows exporting of the private keys
Use Manage Private Keys to set the permissions so the second user can access the private keys
After these steps my second user was able to use the code signing certificate properly.

The container "…" must contain only one certificate and its private key

I am unable to install a mobile provisioning certificate on iOS 5 because I get this error:
The container "…" must contain only one certificate and its private key.
I used the same process that worked in the past but on iOS 5 it doesn't work and I have no idea how to export my certificate in a "desirable" state.
I was able to fix this by exporting the private key from the "Certificates" Category of Keychain, rather than exporting the Key directly.
So export the NAME of the cert, not the private key itself, and you should be good to go.
I think a more specific answer is that you...
open up Keychain app
(I am assuming you already have the key pair of your Identity in a keychain )
Like #Brent Shaffer says, choosing from "Certificates" is more straight forward
(The reason being is that the Keychain App logically groups the Certificate and private key for identities when using the "Certificates" view)
SHIFT-select both your SMIME certificate and its corresponding private key
right-click the selection and choose 'Export 2 Items'
Save as a (.p12) file with a very strong password
email the .p12 file to your email account
And from your iphone Mail app you can tap the .p12 file
and Mail will suggest to import this as a Profile. You will need the password from earlier.

Resources