The task is to import certificate to remote server (win2008 server web edition/ IIS7).
certificate is in .pfx file.
after installation I noticed the private key saved on the client server (from which script is running) (in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys), but not on destination server (where certificate is installed). Due this certificate can't be used for site binding with error:
A specified logon session does not exist. It may be already have been
terminated.
So. I can see certificate is installed on the remote server but private key is not.
What I did wrong ?
Dim pathToPFXFile As String = "\\CertServer\e$\tmp\CPVanitySSLInstall.pfx"
Dim passwordForPFXFile As String = "xxx"
Dim WinVanitySSLTable As Data.DataTable
Dim cert, cert1 As X509Certificate2
Dim certs As X509Certificate2Collection
Dim store As X509Store
cert = New X509Certificate2(pathToPFXFile, passwordForPFXFile, X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable)
store = New X509Store("\\DestinationServerName\My", StoreLocation.LocalMachine)
If (cert IsNot Nothing) Then
store.Open(OpenFlags.MaxAllowed)
store.Add(cert)
store.Close()
End If
BTW when I run this script on destination server itself it works completely as expected.
Except of this i checked access to machine keys store on remote server \DestinationServerName\C$\ProgramData\Microsoft\Crypto\RSA\MachineKeys and it is OK.
You can use certificate manager in windows to verify if the certificate does have an associated private key. Select the cert in the list and click Open or look at the icon if there is a little key in it you have a private key.
If it does have a private key make sure iis or your asp.net app has permissions to access it. You can find the private key file at C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys to check permissions.
Related
We have a service that will generate a CA cert and use that CA cert to sign all other required certs on startup.
The CA cert has an associated private key and is stored in the windows certificate store with Exportable flag. This works fine on most machines but on one of our QA's machine we run into some nasty issues.
When I load the CA cert from the cert store in code and checked HasPrivateKey flag it returns true. Then when I attempt to use the CA cert to sign another cert. It throws keyset does not exist exception.
In the certificate store it says the certificate is valid. On the general page it says
You have a private key that corresponds to this certificate
Good sign! But when we try to right click -> Task -> Export it. The include private key button is grayed out and says
The associated private key cannot be found. Only the certificate can
be exported
We thought its a permission issue so we run mmc in admin mode and still the same result.
On my dev machine I noticed that the private key file is stored in %APPDATA%\Microsoft\Crypto\Keys but its not the case for our QA's machine. We cannot find the private key file in the same folder with the timestamp = CA cert generated time. We also looked into
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\SystemKeys
%WINDIR%\ServiceProfiles\LocalService
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys
but no luck still.
The account used to run the service is Local System so permission shouldnt be an issue here. No special anti-virus installed other than Windows Defender and nothing in Defender's history either.
How can I export the Token Signing Certificate that is created when ADFS 3.0 is installed? When I open up the certificate MMC, I am able to see the certificate however the message 'You have a private key that corresponds to this certificate' is missing and I am unable to export the private key. I read in the article ADFS deep dive: Certificate Planning that I can find it in Active Directory in the following container:
CN=ADFS,CN=Microsoft,CN=Program Data,DC=domain,DC=com
However, although I can get to that container, all I see is a GUID inside and do not know how to export the private key out of Active Directory.
How can I get the private key?
******************************************** EDIT ********************************************
In case anyone comes to this later, the certs are actually in the personal cert store of the ADFS service account but they are NOT exportable. You almost certainly want the SSL cert private key NOT the token signing cert private key. The documentation
I was following to set up ADFS for SharePoint was a little confusing. The private key had to exported for the SSL cert, however the thumbprint of the token signing cert had to be placed in the web config. I was incorrectly trying to export the private key of the token signing cert.
******************************************** EDIT ********************************************
You mean the self-signed ones you get with automatic rollover?
If so, where do you see these with mmc?
They are stored in a combination of an AD container and the ADFS DB.
So you can't export in the normal manner.
For a very good reason - security. If you have the private key you can send / hack anything and it will be accepted as coming from ADFS.
The public key is available in the metadata.
If you have to do this, turn off automatic rollover and use your own certificates.
I'm trying to get this external REST webservice that requires both a server-side certificate and a private key (both of which I got from the publisher as *.pem files of that service).
For my testing, I googled and found a way to combine these two pieces into a *.pfx file - and loading a X509Certificate2 instance from that binary file on disk works just fine.
Now I was trying to put this into the Cert Store on my production Windows Server 2008.
I can get the X509Certificate2 from the cert store in my C# code - no problem:
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySerialNumber, "serial-number-here", false);
if (certs.Count > 0)
{
X509Certificate2 cert = certs[0];
// set the certificate on the RestClient to call my REST service
_restClient.ClientCertificates.Add(cert);
}
store.Close();
But when I do this, then the web service barfs at me, claiming it needs a "SSL certificate"...
Also: when I was loading the X509Certificate2 from disk, from that *.pfx file, I had to provide a password - nothing needs to be provided here, when loading from the cert store.... odd....
It seems that even though I imported the *.pfx which contains both the server-side certificate and our private key, somehow I cannot get both back from the cert store...
Any idea how I can get this to work? Do I need to load the private key from the cert store in a second step? How?
These certificates still remain mainly a big voodoo-like mystery to me ..... can anyone enlighten me?
The first thing to check is to see whether the certificate store does have the private key.
Open up the certificate management snappin and find your certificate, double click it and make sure it has the red highlighted section like in the image below:
Next, if the private key is in the store then maybe the account accessing the certificate does not have permissions on the private key. There are two ways to check this:
In the certificate management snappin, right click the certificate > All tasks > Manage private keys. (You should be able to check and edit permissions here)
In your code you could access the PrivateKey property (i.e. Do var privateKey = cert.PrivateKey and see whether you get it back).
You did not write how is the web service implemented.
if it is deployed on IIS
if it is self hosted
Your code to get certificate from store is correct. The question is where did you import the pfx - CurrentUser or LocalMachine store. You are using CurrentUser store in the code example. If you imported the certificate to LocalMachine store it will not be found. Also, please specify the store name - StoreName.My (in MMC or certmgr.msc it means Personal) in the constructor of X509Store (it might be default, but who knows all the defaults anyway :) )
But when I do this, then the web service barfs at me, claiming it
needs a "SSL certificate"...
You need to ensure you have Client Authentication in the extended key usage of the certificate.
Also: when I was loading the X509Certificate2 from disk, from that
*.pfx file, I had to provide a password - nothing needs to be provided here, when loading from the cert store.... odd....
It's how it works. When you have a pfx then the private key in it is secured/encrypted with password (password can be an empty string). When you import pfx to certificate store then the private key is secured/encrypted with other key (not exactly sure what key it is). However you can add another level of protection to the private key by specifying strong protection when importing pfx to the store (I do not recommend it when used with ASP.NET, or web services or anything that does not have a desktop). But when it is your personal certificate to sign emails then it might be good to enable it. Windows will then popup a window whenever an application will try to use the private key.
#DanL might be right about the rights to the private key and his
1) - set rights on private key and
2) - accessing private key in X509Certificate2
are written OK. I would just add to 1) that you are trying to connect to the REST service from a ASP.NET application or another web service on IIS then the name of the account that you need to add permission for is IIS APPPOOL\name_of_the_apppool_your_app_runs_under
I want to export the certificate and private key from one machine to another so I can reuse the provisioning profile.
There's a private key under the certificate in keychain access.
1)I exported the the certificate as certifcate .cer file then I imported that from another machine. However , it's missiong the private key. and xcode on the new machine complaining no valid signing key available for the imported provisioning profile.
2) Next I try to export the certificate and the private key as personal information exhange .p12 format, this time it prompted me to input a password which I did.
3)I imported the .p12 file into the new machine, this time the new machine complaining error, cannot read the contents.
So, what should I do to properly export both the certificate and private key and import them into the new machine.
Hope it may help you
In Keychain, select three items: Your private key, public key and the cert from Apple
CMD+Click to select "export 3 items"
and you will export one .cer file. Then double click to import the file without keying any password to protect so.
or you should import cert first and then import both public and private key.
Make sure you also have the Apple Developer Relations Root CA certificate in your keychain. That is what is used to verify the certificate. See in your keychain access whether it has been paired correctly.
With Xcode 5.0+, this has become very simple.
1. On the computer with the developer credentials,
Goto Xcode->Preferences->Accounts.
Click on the gears to export the profile. Choose a password as it includes all your credentials of apple-developer program.
2. Share the exported file with the new computer.
3. Import the profile in your Xcode->preferences->Accounts.
My certificate is stored in a custom store under "Certificates(Local Computer)" instead of under "Personal".
Normally, if the cert is located under personal, i just use C:>netsh http add sslcert ipport:0.0.0.0: certhash= appid= certstorename=MY
where, certstorename=MY is already assumed by default if not specified.
This works fine until we were required to store the certificate in a custom store other than the existing personal, trusted people, trusted publishers, etc. etc.
If we called our new store "my cert store", how would the new netsh command look like?
how does the word "MY" map to the "Personal" store? is there a dictionary someplace that maps these?
i checked the System.Security.Cryptography.X509Certificates namespace and there exises an enum called StoreName with the following values:
AddressBook - The X.509 certificate store for other users.
AuthRoot - The X.509 certificate store for third-party certificate authorities (CAs).
CertificateAuthority - The X.509 certificate store for intermediate certificate authorities (CAs).
Disallowed - The X.509 certificate store for revoked certificates.
My - The X.509 certificate store for personal certificates.
Root - The X.509 certificate store for trusted root certificate authorities (CAs).
TrustedPeople - The X.509 certificate store for directly trusted people and resources.
TrustedPublisher - The X.509 certificate store for directly trusted publishers.
I tried all of them on the netsh command as certstorename and i always get this error:
SSL Certificate add failed, Error:1312
A specified logon session does not exist. It may already have been terminated.
What you are trying to do seems correct. Could you retry after applying hotfix http://support.microsoft.com/kb/981506 for a problem which actually matches your symptoms exactly.
A huge flaw is that even if the PrivateKey is not persisted properly, the private key icon will still show up in mmc and it will say "There is a private key associated with this certificate". To know for sure that the private key is being properly imported,
Right click on C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys and take a note of how many files are in the folder (this is where the private keys are kept).
Import the pfx file / however you are adding the certificate/key to the store
Check the file count again of that folder, there should be 1 more file than before
You can try testing this with a newly created, self-signed certificate with a tool like open-ssl. Was stuck on this for weeks until I found this stackoverflow post, Inserting Certificate (with privatekey) in Root, LocalMachine certificate store fails in .NET 4
Another gotcha is to be sure the certificate is in Local Computer (not user), but it looks like you already got that part down.
Open your certificate and double check whether it actually contains a PrivateKey. Depending on how you exported/imported it, it may have been truncated to a public-only data.
In explorer, just double click and check whether "this cert contains private key" warning label is visible on the first tab, just under the expiry dates
I had this problem when the certificate was installed in my local user store, instead of the local machine store. Installing in localMachine/my cleared it up.
Derrick. The certstorename just needs quotes. The AppId is the hardpart. Remove the EnhancedKeyUsageList part if you made a self-signed cert. Otherwise prefer to use a cert designed for a server side certificate.
$appid = "appid={"+(get-host).InstanceId.guid+"}"
$certhash = ls Cert:\LocalMachine\my | where {$_.EnhancedKeyUsageList -Match 'Server' -and $_.subject -match (hostname)}|select -expand Thumbprint -last 1
$cmdline='netsh http add sslcert ipport=0.0.0.0:443 certhash=' + $certhash + ' "' + $appid + '"'
resulting with netsh http add sslcert ipport=0.0.0.0:443 certhash=DD2AA37F947FC61766AF95ADA93DFDC1B171CB8B "appid={723b1673-7ec2-42f2-96c3-e1f5b726feaf}" certstorename="my cert store"
netsh http delete sslcert ipport=0.0.0.0:443
Invoke-Expression $cmdline
SSL Certificate successfully added