Really hoping you can help me with the following.
I have created an .Net Core Application that is run as a windows service.
I'm trying to open a certificate in order to decrypt the app settings.
The certificate I am using on my local machine and the test server is the same certificate.
The Public key for the certificate in question is an X5092.
I have the following code to read the Certificate from the store to get the values.
public void Start()
{
using (var store = new X509Store(Location))
{
store.Open(OpenFlags.ReadOnly);
var signingCert = store.Certificates.Find(CriteriaType, _thumb, false);
_logger.Warning($"Number of certs found {signingCert.Count}");
var firstCert = signingCert[0];
_logger.Warning($"Subject - {firstCert.Subject}");
Thread.Sleep(1000);
try
{
_logger.Warning($"Private Key - {firstCert.PrivateKey}");
_logger.Warning($"Get RSA Private Key Method {firstCert.GetRSAPrivateKey()}");
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
}
}
}
The application finds the certificate using the ThumbPrint enum, the thumbprint and doesn't care if the certificate is valid or not.
The value of firstCert is the cert I am after.
The "Subject" prints to the log file correctly as well as any of the other props apart from the Public and Private Key props.
My application crashes as soon as I call any of the following
firstCert.PrivateKey
firstCert.GetRSAPrivateKey()
firstCert.PublicKey.{anotherProp}
The crashes happen under the following conditions.
The server is rebooting.
The application is set to automatic start up.
The application is run as a service.
The Logon is Local System Account.
When the application does crash, there are no logs after I try to access key data of the cert.
No exception caught, the application fails to start, I only find this out by looking at the services to which is says stopped.
The application works correctly in the following conditions
When debugging on my local machine.
Running as a service, on automatic start, as the Local System Account on my local machine.
As above but started from the services feature.
On the test server but with a delayed start up.
On the test server but started from the services feature.
The app written is .Net5
My local machine is windows 10 enterprise.
The server is 2012 R2.
Related
I'm developing an application in UWP which acts as a server and i made a self-signed certificate and installed it on both the server and client, I checked the certificate if it has a private key and it does, and when I retrieve it from the store programmatically it loads the private key, but for some reason when the authentication handshake starts the server says that "the credentials supplied to the package were not recognized", the only way it works is when I get the certificate as a PFX from a folder...
this one works:
Selectedcert = new X509Certificate2("LocalCertificate.pfx","password", X509KeyStorageFlags.UserKeySet);
this doesn't:
X509Store store = new X509Store(StoreName.Root,StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection cers =
store.Certificates.Find(X509FindType.FindByIssuerName, "localhost", false);
X509Certificate2 Selectedcert = null;
foreach (var c in cers)
if (c.HasPrivateKey && c.PrivateKey != null)
Selectedcert = c;
I checked the manifest and the application has Capabilities to the Shared User Certificates also I checked the certificate permissions and the user does have permissions to read the private-key
Edit:
also i have Tried both StoreName.My and StoreName.Root
i tried the same code in a console application and the authentication handshake is ok, so the problem is with the UWP restrictions, it doesn't let the application to use the private key or something like that
i dont know how to get an X509Cert in UWP if someone knows please inform me, thank you :)
I think the issue is that UWP apps are running in the sandbox so that it has limitations when trying to accessing the localhost. So in your scenario, you could not get the certificates.
Update:
The sharedUserCertificates works for UWP APIs like UserCertificateStore Class and CertificateStores Class. You could check the official sample -UserCertificateStore to see how these APIs could get the certificates from the certificates store.
This question already has an answer here:
X509Certificate2 makes IIS crash
(1 answer)
Closed 5 years ago.
Simply I have X509Certificate2 certifacate which I want to load it in ASP.NET MVC Application.
simply here is the code
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
string path = HostingEnvironment.MapPath("~/Certificates.p12");
// the path is correct, I logged it to a file and it was correct
byte [] certBytes = File.ReadAllBytes(path);
X509Certificate2 cert = new X509Certificate2(certBytes, "some password");
}
}
and even this is not working
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
string path = HostingEnvironment.MapPath("~/Certificates.p12");
// the path is correct, I logged it to a file and it was correct
X509Certificate2 cert = new X509Certificate2(path, "some password");
}
}
in the two previous cases, the code is working on my local machine, BUT when moving this code to our server, then the statement
X509Certificate2 cert = new X509Certificate2(/*whatever bytes or path*/, "some password");
is breaking, actually this statement get my IIS's Application pool to be stopped and I get Http 503 Service Unavailable error when I try to reach the website.
When I remove the previous statement, there is no 503 Error and the website is reachable.
I tried to move this statement to another class (putting it not in the startup of the website) but the result was the same.
EDIT for some very strange reason I can not log the exception which occur.
so I do not know what is the exact problem of this
EDIT I just created a small console application, and I tried to read the same certificate file from it, and it worked perfectly both on my local machine and on the server, so I suspect the problem not from the certificate file and not from the server, but the combination of the ASP.NET MVC project with the certificate file is producing this problem
EDIT
Here is the Event log of the server
Application pool 'SmaresDev' is being automatically disabled due to a series of failures in the process(es) serving that application pool.
A process serving application pool 'SmaresDev' suffered a fatal communication error with the Windows Process Activation Service. The process id was '8520'. The data field contains the error number.
A fatal alert was generated and sent to the remote endpoint. This may result in termination of the connection. the TLS protocol defined fatal error code is 10. The windows SChannel error state is 1203.
Any Ideas.
I was experiencing something similar with a crash where no exceptions were being caught. I had the similar issues in the event viewer and also ran into the same thing with the console application working fine. I fixed it as the following
X509Certificate2 Cert = new X509Certificate2(path, "some password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
I'm not sure why it works, but it did for me, and hopefully does for you too.
I have 2 server side (dummy) programs which creates a TCP server (TCPListener) and then tries to authenticate the server with X509 certificates (BeginAuthenticateAsServer).
The client program is ready.
The difference between the two server side program is that one of them is a simple console application while the other is a Windows service.
For some reason client can connect to the console application but not to the service. Design is the same in both program.
I'm using the following line to describe the certificate I will use:
serverCertificate = new X509Certificate( "C:\\Users\\Tom\\workspace\\ServerSSL.cer", "12345678" );
I think something is fishy about privilages with the service program but I could not figured out in the last couple of days. Of course, I have the The server mode SSL must use a certificate with the associated private key. error. When I tried to search for answer as help, I got results in topics of IIS / webservices but I'm using a simple Windows 7 Pro.
May I ask your help?
The file ServerSSL.cer most likely contains only certificate, not the private key. That's what the error message tells you.
Try to find pfx or p12 file. Or if you have separate file that contains private key (i.e. .key) you need to make a pfx (p12) file from both of them (.key and .cer). You could use openssl or xca to do that.
Background:
I have a Windows Service which polls Azure subscription logs (API: http://msdn.microsoft.com/en-us/library/windowsazure/gg715318.aspx)
On my local development machine the service is set to log on as my account. The X509 certificate was imported under CurrentUser\Personal and in the source code where I check the cert store I have:
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
Issue:
The service works fine on my dev machine, it can retrieve data from the API.
On the testing machine I get this error:
The remote server returned an error: (403) Forbidden.
The service is set to log on as a specific user, dmz\aaseclg1 and the current user\personal cert store has the required certificate.
Any ideas?
Thanks in advance.
Edit: image of password prompt:
I have seen this error when I export the certificate from the machine on which it is created and while exporting, I choose to import it in .cer format (i.e. without exporting private keys). Can you try by exporting the certificate from your dev box in pfx format and then copy the file on your test box and import it again in your test box by selecting the file and installing the certificate?
UPDATE
I was able to reproduce this. When you import the certificate, please make sure that you have unchecked the checkbox which reads "Enable strong private key protection" as shown in the screenshot below.
When I check this checkbox, every time I use this certificate it prompts me to enter a password. Now I was using a GUI application so I could see that box. In your case since you are consuming the certificate through a Windows Service (a non UI thingie), this box never shows and you think the service is hanging.
I have a black box service I have to call into with simple rest commands that returns xml.
They issued us a certificate that had to be run in IE and installs in to IE's Certificate section. As per their instructions I exported it with the entire chain as a pfx with password.
On the machine that the cert was issued directly to, everything works fine in code
var certHandler = new WebRequestHandler();
certHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
certHandler.UseDefaultCredentials = false;
var certificate = new X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); //Must be renewed and replaced every year.
certHandler.ClientCertificates.Add(certificate);
//Execute the command
var client = new HttpClient(certHandler);
string result;
try
{
result = await client.GetStringAsync(url);
System.Diagnostics.Debug.WriteLine(result);
}
catch (Exception ex)
{
throw ex;
}
(I've stored the cert in the resources, but it loads fine and loading it from a file works fine too in developer machine.) I also imported it into IE on the server just in case. Obviously this is likely under the wrong cert store, but I couldn't figure out how to load this in globally. I can tell you that the same REST GETs work in IE on the server just like they do on the developer machine. It's only in code that it fails.)
In production, this same code throws a 403 forbidden.
Production (really a beta server) is actually behind the same nat as the as the development machine so they're seeing the same IP come through etc.
Any ideas why it would fail on the server and not on the developer box?
Thanks!
You should use X509KeyStorageFlags according to account under which your app is running. If it is
1) An app that runs under regular Windows User Account you should use
X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.UserKeySet);
2) Windows Service under LocalSystem, IIS under NetworkService or other services under built in Windows Account, you should use
X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.MachineKeySet);
Basically, you shouldn't use X509KeyStorageFlags.PersistKeySet in your case - you import certificate from pfx format every time.
Certificate's private key is storing in the container according to flags. So you may have no access to it if you use wrong flags.
DefaultKeySet is not just alias for UserKeySet (msdn) - so choose appropriate flags in every case.
These articles also may be helpfull:
Key Storage and Retrieval
Eight tips for working with X.509 certificates in .NET
How Certificates Work
What I've found is that for whatever reason it won't allow you to grant permissions properly to the key. To work around it, I went to:
X:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys
In explorer and found the key in question (I used deduction by Date but the thumbprint is there so you should be able to match it up.) and then right clicked, took over the file permissions and then set the permissions manually.
Then my code just started working.
Interestingly however, on another machine that I needed to deploy this to, the file doesn't exist in the machinekeys directory so I don't know what I'm going to do there but...