PFXExportCertStoreEx to export private and public keys - windows

I have used PFXExportCertStoreEx API to successfully export public and private key of a RSA certificate from Windows key store.
Can the same PFXExportCertStoreEx be used to export public and private keys of DSS and ECDSA certificates from the Windows key store?
If not what other API needs to be used?
Thanks in advance.

After days of analysis and discussions, finally I was able to identify the root cause. It is related to privileges. If I run with Admin privilege, I can use PFXExportCertStoreEx to extract keys for ECDSA certificate as well from the Local Machine certificate store.
If you do not intend to use Admin privilege, just take the certificate manager or mmc and select the certificate, take All tasks > Manage Private Keys give privileges as required.

Related

Export certificates and private key from Windows 10 certificate store which is deployed through Active Directory

I have deployed certificate and private key using AD group policy which deployed certificate and private key to the client machine. When I tried to export the certificate and private key from the client machine, the private key export option was disabled. I have enabled the private key export option when imported to the AD group policy. But that didn't help me to export the private key from the client machine. Certificates export worked well from the client machine without the key.
I would like to export this certificate and key from the client machine (export in any format). Can anyone help to do this?
Thanks in Advance.

C# X509Certificate2: Where to store the private key?

I have a self-hosted WCF application, which acts as a server and I want to install/deploy it on a Windows machine.
The application uses a self-signed certificate, which I created with makecert.exe. So the PFX, CER and PVK are there and available. Everything works fine.
At this point of time and only for testing, the application reads the certificate and the private key from an embedded resource. That means both are compiled into the application, which is a high security risk.
I already know, that the most common way to store this data, is the windows certificate store. And I also know, how to save and read from the windows certificate store.
But there is something, that I still do not get:
Where do I store the private key (PVK) for the certificate (CER), so that my application is able to use the CER?
I mean, if my application can read it, then anybody, who has access to this machine, can read it. Or is this wrong?
Do I have to take care myself or is there any "industry standard" for windows machines, to save and read the PVK?
Windows certificate store is the most common place to store certificates (i.e. CA) or certificates with private key (End entity).
If you store certificate ( with private key - PFX) in LocalMachine\My store then you can assign privileges who (what account) can access private key. It is done through certlm.msc tool. System account has access by default so any system service can use the private key.
There are other ways to store private key (like smartcard, HSM, net HSM etc.) and other ways to access private key (like PKCS#11).

OS X how to check certificate is signature

Is there a way to check a certificate is signed by a given root certificate using SecureTransport API similar to OpenSSL X509_verify?
On OS X, the API to create and manipulate certificates is the Certificate, Key, and Trust Services:
Certificate, Key, and Trust Services is a C API for managing
certificates, public and private keys, symmetric keys, and trust
policies in iOS and OS X. You can use these services in your app to:
Create certificates and asymmetric keys
Add certificates and keys to
keychains, remove them from keychains, and use keys to encrypt and
decrypt data
Retrieve information about a certificate, such as the
private key associated with it, the owner, and so on
Convert
certificates to and from portable representations
Create and
manipulate trust policies and evaluate a specific certificate using a
specified set of trust policies
Add anchor certificates
See for example:
SecTrustCreateWithCertificates - Creates a trust management object based on certificates and policies.
SecTrustEvaluate - Evaluates trust for the specified certificate and policies.
SecTrustSetAnchorCertificates - Sets the anchor certificates used when evaluating a trust management object.

Private key security in windows certificate store

When I import a public/private pair into windows certificate store, Windows does not require any password of any kind to encrypt the keys.
From that I conclude that if it is a user's store, it uses the user's password (or probably the user's hashed password) to encrypt the private key, and, if it is the local machine store, it is probably some kind of hardware-based key to encrypt the private key.
Did I get it right???
And if I did, what is the point of non-exportable keys if I can decrypt the keys???
And last question - If I got it right up to here, what are the alternatives?
As "SLanks" link explains, the private keys are encrypted with the user's password or the machines's password (depends on the location of the keys in the store).
Therefore, anyone who can log to the machine can obtain to this user's keys and anyone who has access to the machine can obtain keys stored for the local machine.

PrivateKey trust permissions for local machine "Trusted roots" certificates

I have a certificate that has to be imported into Certificates/Trusted Root Certification Authorities and has a corresponding private key.
To actually access the key from code you need to set private key permissions to grant full access to particular IIS application pool. I totally understand that but the problem is that this can only be set on personal certificates and not trusted root ones.
I've tried adding the same certificate to Personal store and the following code doesn't break:
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 cert in store.Certificates)
{
if (cert.HasPrivateKey)
{
// access private key here
}
}
store.Close();
Setting permissions on certificate in personal store works if I change StoreName.Root to StoreName.My. I'm able to access it there. But I'm not able to access it in root. It just says:
Keyset does not exist
Any suggestions?
Additional information
If I set my application pools identity to Local System (which has total permissions over my machine) I can successfully access private key. So the main question is how do I set permissions on my application pool identity to have access to private keys for certificates in the Trusted Root store.
Why trusted root store and not personal?
I have a pre-built assembly that accesses this certificate in this particular store, so simply placing the certificate in Personal store won't do the trick for me. That's why setting trust permissions on private keys of trusted root certificates is imperative.
I haven't tried this with the Trusted Root Certification Authorities but what I have found is the simplest thing to do with other Certificate Stores is to drag and drop the certificate into the Personal Store and then set permissions and then drag and drop back to the original certificate store. In your case the Trusted Root Certification Authorities.
Steps using Certificates MMC:
Import certificate to the store you want it and mark keys as exportable. (You might be able to bypass this and import directly to the Personal Store, but I haven't tried.)
Drag and drop the imported cert to the Personal Store.
Right click the certificate in the Personal Store and in the context menu, click "All Tasks", then in the submenu click on "Manage Private Keys". Set the appropriate permissions according to your app pool as referenced in step 1.
After permissions have been set, drag and drop the certificate back to the original store (in your case the Trusted Root Certification Authorities).
Solution
It is possible to set trust permissions on certificates other than those in Personal certificate store, but you can't set permissions via MMC. At least not directly on the store that is. Accepted answer shows a simplified approach with moving certificates around to achieve the same result.
You have to do it this way...
Getting the tool
Get WF_WCF_Samples file from Microsoft. This is a self extracting archive, but you won't need to extract everything. So...
Open the file with any archiver tool and only extract FindPrivateKey solution/project
Open in Visual Studio and compile it.
Finding your private key
Open MMC and add Certificates snap-in. Make sure you select Computer and Local Machine when adding it.
Select the store that has your certificate with private key.
Open private key and copy its Thumbprint
Open command prompt and navigate to the folder where you compiled your FindPrivateKey tool
Enter this command
FindPrivateKey YourStoreName LocalMachine -t "ThumbprintWithSpaces" -a
ie.
FindPrivateKey Root LocalMachine -t "83 45 22 ..." -a
Copy file along with path (it will liekly span over two lines so copy to Notepad and concatenate)
Grant certificate trust
open command prompt and enter:
icacls "FullPathOfYourPrivateKey" /grant:r "UserFQDN":f
ie.
icacls "c:\ProgramData..." /grant:r "IIS AppPool\ASP.NET v4.0":f
Done.
This will grant certificate private key full trust to your user (in my case above it's application pool identity) so you can use the key to sign data or do whatever you need to do with it.
In case you don't want full permissions, you can easily change the last part after colon. It can have many different settings, so I urge you to check icacls command help.
If you are using Windows Server 2003, you'll notice that you don't get the Manage Private Keys task under your certificate.
If you install Microsoft WSE 2.0 on to your machine, you can use a tool called X509 Certificate Tool. Just search for your cert, its more than likely in (or should be) in Local Machine / Personal Store.
NOTE: if you have your cert in Current User / Personal Store (which often is the default), it will only be accessible to the user that is currently logged in, which means if you want your webserver to access it, it can't without changing permissions to your AppPool.
You should be able to change the permissions to the private key very easily, by default, your AppPool on your webserver will be using NETWORK SERVICE to run your web application. So just add NETWORK SERVICE to the security and by default it will set the Read and Read / Execute permissions which is sufficient for your BouncyCastle, etc, to read the private key so you can sign your document.
Hope this helps.

Resources