-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue with new X509CertificateLoader #109007
Comments
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones |
What version of .NET 9 are you using? There was a problem where the loader meant to load the private keys into the newest Windows cryptographic engine, but accidentally caused them to load into the oldest. That got fixed for RC2. A workaround in the meantime would be to specify a loader limits like Pkcs12LoaderLimits limits = new Pkcs12LoaderLimits
{
PreserveStorageProvider = true,
};
...
certificate = X509CertificateLoader.LoadPkcs12FromFile(
path,
password,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable,
limits); If that fixes your problem then you shouldn't see it anymore in RC2 or the full release version. You (probably) won't want to do it long-term, though, since the main reason the storage provider isn't preserved is so that legacy CAPI keys will instead get upgraded to CNG keys. |
Sorry, I should've been clearer and specified that I am actually using RC2. Since my previous post, I discovered that it seems even the old code stopped working in .NET 9 RC2. I had refreshed 6-8 or so times when I tested before making the post and thought it was working (usually, every even request would work and odd request would not), but I guess I got lucky and all my tests went to the same server. I ended up having to put the project back on .NET 8 to get it working correctly. I will try your suggestion and let you know how it goes. If it isn't working, I'll put together a little project to help reproduce the issue. |
LoadBalancerDemo - .NET 9.zip Here's a bit more info. I have created a sample project (attached). The difference between the .NET 9 and .NET 8 attachments are:
Version of .NET 9 I have installed based on MSBuild file path seems to be: The project uses minimal APIs and contains two endpoints:
The project is using The two endpoints: app.MapGet("/weatherforecast", async (HttpContext httpContext, [FromServices] IAntiforgery antiforgery) =>
{
// Validate anti-forgery token
try
{
await antiforgery.ValidateRequestAsync(httpContext);
}
catch (AntiforgeryValidationException)
{
return Results.Forbid();
}
WeatherForecast[] forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return TypedResults.Ok(forecast);
});
app.MapGet("/antiforgery", (HttpContext httpContext, [FromServices] IAntiforgery antiforgery) =>
{
AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(httpContext);
httpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.NoContent();
}); .NET 9-rc2First request, sending request to the
Second request, sending request to the
As per above logs, a (Of interest: you'll see later that the .NET 8 project does not create an additional file here like it did in .NET 9, and also did not get the cannot find file error) Despite this error, the server response was
Now send request to Server returns the expected response of
Server logs:
Send same request again, this time get
Send same request a 3rd time, this time get
So the exception occurs on the Pkcs12LoaderLimits workaroundI tried the same again with .NET 9 and the suggested .NET 8Now, here's the logs for the same but with the application running as .NET 8. Just to make sure there was nothing crossing over between requests (like cookies being persisted), the requests I sent for .NET 9 above were using Postman, while the requests below for .NET 8 are sent using Bruno (an alternative application similar to Postman). First request,
Next request to
Logs - note no "cannot find the file specified" error appears. Also of note, no extra .xml key file was created.
Now send request to
Sent the request an additional 4 more times, works fine - all of them returned
Hope this helps. Let me know if there's anything else I should try. |
Description
Hi there,
Our production environment runs two IIS servers behind a load balancer. To allow cookies to be decrypted by both servers, we do the following in our Program.cs in current .NET 8 projects to load a .pfx certificate file from disk.
This has worked fine until now, but when trying out the .NET 9 preview, we got the warning about the X509Certificate2 constructor being obsolete during compilation.
So I've adjusted as follows, replacing the
new X509Certificate2()
withX509CertificateLoader.LoadPkcs12FromFile
and keeping the same storage flags.The application runs fine locally on my machine, but in production behind the load balancer, it's not working correctly. When you log into the application, if your request goes to server 1, then any further requests that go to server 1 work fine, but any requests sent to server 2 fail. This issue is the behaviour I would expect by default if doing nothing of the above.
Changing back to the obsolete constructor (even while the project is still using .NET 9) resolves the issue.
Is there something I'm doing wrong with the new one or is it a bug in the new one, such as with how it's handling the flags?
Reproduction Steps
Code sample provided above.
Expected behavior
Requests to both servers behind the load balancer should continue to work as it did before.
Actual behavior
Cookies cannot be decrypted if created by the other server.
Regression?
Still works fine with the obsolete constructor even with the project using .NET 9.
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: