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.
Related
This bounty has ended. Answers to this question are eligible for a +50 reputation bounty. Bounty grace period ends in 22 hours.
whisk is looking for an answer from a reputable source.
I created an image uploading app for a client and they want to host it on its own IIS server. When I publish the app to the server I get the error
HTTP Error 500.30 - ASP.NET Core app failed to start
I have installed all the .NET v6 SDK, Runtime and hosting bundle that is needed to host the app.
After looking around on SO and google I was able to run the appNameHere.dll from the command prompt and it runs just fine without showing any errors. When I do that I can open it locally on the server and have the app show up. It's just when it's public facing I get the error.
I have narrowed it down to these few lines of code in the Program.cs file
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.GetFullPath("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\ItemImages\\")),
RequestPath = new PathString("/ItemImages")
});
When I comment these out, the app shows up fine and works, but I can't get the files from the other site.
I can also set up a folder locally in the "C:\UnitImages" and everything works as well.
I created a shared connection to the main server to test the path as well and it works there too. So I'm a bit lost on where to go next.
Update
As stated in one of the links from #Code Maverick I have updated the Application Pool Identity to the user that has full access to the folders and I still get the Error that's stated above.
I came across this article and tried it but I'm getting an error 'NetworkConnection' is a namespace but is used like a type
repo for ref.
var sourceCredentials = new NetworkCredential { Domain = "12.34.56.789", UserName = "Administrator", Password = "123456" };
using (new NetworkConnection("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\UnitImages\\", sourceCredentials))
{
// to serve static froms from \\network\shared location
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.GetFullPath("\\\\12.34.56.789\\c$\\ABC\\FolderName\\ProjectName\\Images\\UnitImages\\")),
RequestPath = new PathString("/UnitImages")
});
}
Based on this and this, you may need to provide IIS_IUSRS group the ability to write to the share.
You personally may be able to access the share, but your web application hosted within IIS needs the same access privilege. This does have security implications though.
I'm trying to instantiate a X509Certificate2 object in a Web Job, in an Azure App Service. The certificate is a PFX file.
When I try to instantiate like this, it fails to use the object in a WS call:
new X509Certificate2(byteArray, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.EphemeralKeySet)
By failing, I mean it starts throwing:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
But when I try like this, the WS works correctly:
new X509Certificate2(byteArray, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.UserKeySet)
The only difference is the user of X509KeyStorageFlags.EphemeralKeySet. The app is running on .Net Framework 4.7.2. Does anybody know why this happens?
A little explanation: we've had a issue with disk space in the App Service and we've read in some articles and in some SO questions/answers that this could have been caused by the fact that Windows writes to disk all certificates read, thus consuming a lot of space.
One example is this question.
SslStream, on Windows, can't work with EphemeralKeySet keys. The underlying reason is that Windows doesn't do TLS in-proc, but does all of the crypto operations in a different process. Their current functionality doesn't try to export/transport ephemeral keys to that other process, so it fails on the other side with "I can't find the private key".
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.
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.
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...