I am getting the net::ERR_CERT_AUTHORITY_INVALID error in ASP.NET Core when I try to request my Web API from an SPA.
The first solution to fix the issue was to go my ASP.NET Core address from browser Advanced - Proceed to localhost (unsafe) and after that the requests from my SPA would work. But I would have to repeat the procedure each time I am starting to work on my project.
Another solution I found was this. In a nutshell the solution is to run the command: dotnet dev-certs https --trust. I am on Windows, so according to the linked article On Windows it'll get added to the certificate store.
But after I run the command I am still getting the net::ERR_CERT_AUTHORITY_INVALID issue on requests. What could I do about it?
Running the command dotnet dev-certs https --trust will create a self-signed certificate in your device. This certificate will be issued to the localhost domain. In my case, after running it, the certificate was created but it was not added to "Trusted Root Certification Authorities".
To add the certificate, you will need to open certmgr.msc (win+r and run certmgr.msc), then go to "Personal" certificates and export the .cer certificate issued to localhost with the correct expiration time.
If you cannot find the certificate there, you can go to the browser and click on the not secure connection icon, then open the invalid certificate and go to the Details tab and click "Copy to File...", which should create also a .cer certificate.
Next, go to "Trusted Root Certification Authorities" and import the certificate there. Once that is done, the certificate will be valid in your local machine. You may need to restart the browser and the service.
In your application, add a reference to the Microsoft.AspNetCore.Authentication.Certificate via NuGet package. Then in the Startup.ConfigureServices method write this:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(
CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate();
// All other service configuration
}
Also add app.UseAuthentication(); in the Startup.Configure method. Otherwise, the HttpContext.User will not be set to ClaimsPrincipal
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
// All other app configuration
}
Source: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1
Do this in the order
dotnet dev-certs https --clean
Remove your keys and pem from AppData\Roaming\ASP.NET\https
dotnet dev-certs https --trust
Run SPA project with "start": "set HTTPS=true&&react-scripts start"
If you run your project(Point 4) before anything else. The authority is not trusted(done by 2) and results in authority invalid errors
I followed these steps and it didn't stop the "Not secure" message appearing in Chrome. So then I tried commenting the following line //app.UseHttpsRedirection(); in startup.cs in the Configure() method and it fixed the problem.
Related
My ASP.NET server was running fine on Friday. Today (Monday) I can't even start it. Error is:
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
I have tried dotnet dev-certs https --trust many times to no avail. Each time it gives me the prompt to trust the certificate, each time with a different thumbprint.
... but nothing changes, the server still fails with the same error message. dotnet dev-certs https --check just says No valid certificate found. I have tried dotnet dev-certs https --clean which claims to succeed (but does not display any prompts), then dotnet dev-certs https --trust but still the same error when I start the server.
I have tried looking in the certificate manager in control panel (certmgr.msc) because doing so seemed to help someone else (on a different site) to solve the same error, but I have to admit I am none the wiser for having looked. Here's what shows up under Personal:
I have discovered that the server runs fine through IIS, running using the IIS profile from Visual Studio 2019. Ok, I could go adapt the client code to talk to a different TCP port, OR learn how to change the IIS server port (launchSettings.json right?).. but I would rather understand what has actually broken here, and learn how to fix it properly.
In case it helps, my Startup.Configure() says:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// for options and correct order, see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
So:
How do I get a dev certificate into the default certificate location (wherever that is??) in a way that actually works? <-- my preferred fast solution today :/
Or, how do I create a dev certificate myself, and how do I tell my server where to find it?
Or, how do I make a real certificate (from my organisation's "official" certificate??) and then how do I use that to get client and server to actually check it, for good security? <-- my goal eventually, but I don't currently know enough yet to be able to do this - currently, my security comes from running client and server on a separate network.
Here's what finally worked for me.
The problem was that although the Certificate Manager was not showing any expired ASP.NET certificates, the Certificate Manager was only looking at the local machine store, not the user store.
I went to the Management Console (mmc from command line) and added a Snap-in for Certificates, for current user.
When I then ran that, I found a whole bunch of ASP.NET certificates under Personal / Certificates AND Trusted Root Certification Authorities / Certificates, some of them expired. I deleted all of them.
I then ran dotnet dev-certs https --trust again, and then my server started. Yay!
You need to delete all certificates issued for localhost, best way how to do it is with this Powershell script:
Get-ChildItem -Path Cert:\CurrentUser -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item;
Get-ChildItem -Path Cert:\LocalMachine -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item
After that you will be sure that all certificates issued for localhost are gone.
Then run
dotnet dev-certs https
That's it!
I'm creating an ASP.NET Web API endpoint inside a console app which I need to host as a Windows Service.
Now everything is working except the endpoint is in http. I want to use https.
When I run it via Visual Studio.
I believe the Kestrel is behind an IIS as a reverse proxy and SSL certificates are validated. But when I host it as a Windows service. I'm getting certificate errors when trying to reach the endpoint
This is my Kestrel WebHost builder
var configigurations = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.Build();
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps("sslcertificate.pfx", "ssl#123");
});
})
.UseUrls(config.ApiBaseUrl)
.UseConfiguration(configigurations)
.UseStartup<Startup>()
.Build();
host.Run();
Since it runs as a Windows service and exposes the API, I cannot rely on IIS. I need to configure for Kestrel.
But how can I
Generate an SSL for localhost (I'm using Windows)
If I have already an SSL certificate in production (*.cert). How can I make a *.pfx (cert + RSA private key) from it on production server (also Windows)
This will create a certificate
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
This will create a trust
dotnet dev-certs https --trust
.Net Core (and .Net 5) is bundled with a convenient tool to handle development self-signed certificates. Look into dotnet dev-certs. The commands are:
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust
This doc also describes how to do the same thing with PowerShell or openssl if that's your style
Look into this question. In short, you can do that by exporting certificate from Windows Certificate store and choosing "Yes, export Private key" which automatically enabled PFX format
Recently, my localhost certificate is expired, I have gone to "sertmgr.msc" remove all localhost certificate and restart the VS and add a new localhost certificate to windows.
But when am I running my application again, still use the old expired certificate not the new one, does anyone know how to fix that?
I have already run the command show below.
dotnet dev-certs https --clean
dotnet dev-certs https --trust
Expired Cert
Cert In Cert Manage
I managed to hack my way around this issue:
Before you do anything, clean the old certificate and generate a new trusted one.
dotnet dev-certs https --clean
dotnet dev-certs https --trust
And if the process above fails, manually remove the certificates before retrying the clean/trust commands.
Get the User Secrets ID of the Web Application you're having trouble with. Search for UserSecrets.UserSecretsIdAttribute(" in your project folder and take the GUID.
Go to %APPDATA%\Microsoft\UserSecrets and open the folder containing the GUID of the problematic project you are struggling with and leave it open.
Create a new Asp .Net Core project, get its secrets GUID, go to the corresponding secret folder (%APPDATA%\Microsoft\UserSecrets\GUID), and open the file secrets.json. You should see something like this
{
"Kestrel:Certificates:Development:Password": "8353f2ec-3cc0-4052-9776-9585b6abd346"
}
Copy that setting from the newly created project secrets.json and use it to override the development password on the secrets.json of the broken project
This way, I've managed to get my old project to use the newly generated certificate. It is hacky, but it works
Based on Pedro's answer,
I used:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
to clean/replace the old certs.
Then I went to:
%APPDATA%\Microsoft\UserSecrets
And deleted all the folders found there.
Now my application runs without complaining.
Creating a new .net core 6 application and running it didn't create a new folder, so I don't know if it's no-longer required.
I assume you're using IIS Express to host your application. If so, it sounds like you're missing linking the certificate to your application(s) as described in this blog post:
Go to C:\Program Files (x86)\IIS Express and run the following from the command line, entering the proper port number and the new certificate thumbprint:
IisExpressAdminCmd.exe setupsslUrl -url:https://localhost:PORT/ -CertHash:THUMB
I want to provide some context about Pedro's answer on Windows.
Thanks to this article and some testing, I found out that the password specified by Kestrel:Certificates:Development:Password setting applies to a project dedicated certificate found in %APPDATA%\ASP.NET\Https.
Answer: When you delete either the password setting or the project certificate, Kestrel starts working as expected, looking for a proper certificate installed with dotnet dev-certs command. I think the most convenient is to delete all project certificates from %APPDATA%\ASP.NET\Https folder.
This seems to be a Visual Studio problem when the project was created. However, I could not reproduce it with my current version of Visual Studio 2019.
In conclusion, the problem is not about the dotnet dev-certs command, but rather about hidden logic on how Visual Studio creates the project and how Kestrel handles certificates.
I had the same problem with different types of projects:
ASP.NET Core with Angular template created with VS Code.
ASP.NET Core Web API created with Visual Studio.
When the problem comes with the ASP.NET Core with Angular template on Windows, you can try:
Stop the application.
Open the File Explorer.
Paste %APPDATA%\ASP.NET\https into the address bar and press enter.
It will navigate automatically to C:\Users\[your_user]\AppData\Roaming\ASP.NET\Https
Delete the your_npm_package_name.pem and your_npm_package_name.key files.
your_npm_package_name: Is the name property value of the package.json file of your Angular client app.
Open MMC (Start > Run > MMC). Open the Certificates Snap-in (File > Add/Remove Snap-in).
Select My Current Account when prompted.
Under Certificates - Current User select the Personal\Certificates folder.
Locate and select the certificate for localhost domain and with the Friendly Name "ASP.NET Core HTTPS development certificate".
Delete the localhost certificate.
Repeat the localhost certificate deletion process for al localhost certificate with the Friendly Name "ASP.NET Core HTTPS development certificate" under the Personal\Certificates folder and the Trusted Root Certification Authorities\Certificates folder too.
Start your application again.
Your application's pem and key files will be automatically regenerated.
This solution is also valid for other advanced templates like Jason Taylor's Clean Architecture Solution Template.
When the problem comes with a ASP.NET Core Web API project created with Visual Studio and enabling Docker (not always).
After trying all the alternatives of this question and using the Generate self-signed certificates with the .NET CLI and Enforce HTTPS in ASP.NET Core guides from Microsoft, I found that my expired certificate was located in the C:\Users[your_user]\AppData\Roaming\ASP.NET\Https folder with the name my_api_assembly_name.pfx.
How did I regenerate my certificate?
Stop the application.
Open the File Explorer.
Paste %APPDATA%\ASP.NET\https into the address bar and press enter.
It will navigate automatically to C:\Users\[your_user]\AppData\Roaming\ASP.NET\Https
Delete the your_my_api_assembly_name.pfx.
Open MMC (Start > Run > MMC). Open the Certificates Snap-in (File > Add/Remove Snap-in).
Select My Current Account when prompted.
Under Certificates - Current User select the Personal\Certificates folder.
Locate and select the certificate for localhost domain and with the Friendly Name "ASP.NET Core HTTPS development certificate".
Delete the localhost certificate.
Repeat the localhost certificate deletion process for al localhost certificate with the Friendly Name "ASP.NET Core HTTPS development certificate" under the Personal\Certificates folder and the Trusted Root Certification Authorities\Certificates folder too.
Open your Windows Terminal as administrator.
Run dotnet dev-certs https -ep $env:USERPROFILE\AppData\Roaming\ASP.NET\Https\your_api_assembly_name.pfx -p your_user_secrets_id:
Change your_my_api_assembly_name with your own assembly name.
How to retrieve your_user_secrets_id?
Open your_project.csproj with a text editor (or double-click on the project in Visual Studio Solution Explorer) and look for a node called UserSecretsId. Inside this node there is your your_user_secrets_id.
Otherwise, if you don't have the UserSecretsId node in your project file:
Open the File Explorer.
Paste %APPDATA%\Microsoft\UserSecrets into the address bar and press enter.
It will navigate automatically to C:\Users\[your_user]\AppData\Roaming\Microsoft\Secrets
Open the folder called as the GUID of your project (you can get yours inside your your_solution.sln file).
Open the secrets.json file and find a property called Kestrel:Certificates:Development:Password. The value of this property is your your_user_secrets_id.
Your application's pfx file will be automatically regenerated.
Run dotnet dev-certs https --trust.
You will be prompted to install a new certificate for localhost.
Click Yes.
Start your application again.
Update:
Just tried the official example https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/fundamentals/servers/httpsys/samples/3.x/SampleApp and it doesn't work.
Brower message:
This site can’t provide a secure connection
localhost sent an invalid response.
Output:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:\Users\xxx\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
warn: Microsoft.AspNetCore.Server.HttpSys.MessagePump[0]
Overriding address(es) 'https://localhost:5001, http://localhost:5000'. Binding to endpoints added to UrlPrefixes instead.
info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
Start
info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
Listening on prefix: http://localhost:5005/
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5005/
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Users\xxx\Downloads\AspNetCore.Docs-master\AspNetCore.Docs-master\aspnetcore\fundamentals\servers\httpsys\samples\3.x\SampleApp
I created a new Blazor application with Windows Authentication. (Visual Studio 2019 V16.4.0, .Net Core 3.1).
Now Windows Authentication works (the top right corner of the web page shows "Hello Domain\Username!") when running with IIS Express in Visual Studio. But Windows Authentication is not working when running as Kestrel application.
I followed the steps in the following link to make Windows Authentication work with Http.Sys. (BTW, I tried [Kestrel/Negotiate][1] but no luck)
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys?view=aspnetcore-3.1
Basically, it just adds the call of webBuilder.UseHttpSys() in CreateHostBuilder() in Program.cs.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = true;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
// options.UrlPrefixes.Add("http://*:5005");
});
webBuilder.UseStartup<Startup>();
});
However, running the application will get an error page with message of
This site can’t be reached
The connection was reset.
or
This site can’t provide a secure connection
localhost sent an invalid response.
Edge's error messages are:
There was a temporary DNS error. Try refreshing the page.
Error Code: INET_E_RESOURCE_NOT_FOUND
IE error message:
Can’t connect securely to this page
This might be because the site uses outdated or unsafe TLS security settings. If this keeps happening, try contacting the website’s owner.
The solution is to relocate your certs, and do a bunch of manual configuration that doesn't seem like it should be necessary: I was following the Configure Windows Server section of the http.sys example fairly closely, but ran into issues with the netsh http sslcert commands. The problem is with where dotnet dev-certs https --trust installs the certificate! In What is the default location for certificates created using "dotnet dev-certs https" it's pointed out that that tool installs certificates in the current user's certificate store, not the local computer store. I had to add both certificate stores to mmc and copy the localhost cert over into Certificates (Local Computer)\Personal\Certificates, at which point the sslcert command completed, and when I ran the test application, it was successfully able to connect with TLS.
I have a WinForms application that consumes a WCF, and pass as a parameter to a function a certificate:
mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...
In WCF service, I recreated the certificate from the array of bytes:
public void SendDocument (byte[] binaryCert)
{
X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...
But when using the certificate to sign a xml, I got the error "Keyset does not exist":
if (cert.HasPrivateKey) // WORKS!!!
{
signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...
In my computer, the application works 100%! But in the WebServer, I got this error!
The question is: even X509Certificate2 recreated from an array of bytes, I need some special permission to access private key?
Thank you!
If you are using windows server 2008 or windows 7, then you need the permission to read private key.
use FindPrivateKey tool to find path.
For example:
FindPrivateKey My LocalMachine -n "CN=MyCert" –a
it returns the path: C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys[File Name]
Go to that path and open file properties
Go to security tab
Click on "Edit" then "Add"
In opened dialog write: IIS AppPool\[your application pool name] and click OK
Now your application pool has permission to read this private key.
I have faced this issue, my certificates where having private key but i was getting this error("Keyset does not exist")
Cause: Your web site is running under "Network services" account or having less privileges.
Solution: Change Application pool identity to "Local System", reset IIS and check again. If it starts working it is permission/Less privilege issue, you can impersonate then using other accounts too.
I was facing the same issue, and I don't know how(shame on me), but it worked:
var certificate = new X509Certificate2(filePath, password,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
certificate.PrivateKey; // before: error "KeySet does not exist"!
using (certificate.GetRSAPrivateKey()) { } // pure black magic
certificate.PrivateKey; // after: just works! lol
I hope someone can answer this mystery.
Vano Maisuradze answer works. If you are looking for the FindPrivateKey tool it is included in Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4, which can be found here: http://www.microsoft.com/en-us/download/confirmation.aspx?id=21459
Once downloaded and extracted, open the project: WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS in Visual Studio and compile it. Then open command prompt and navigate to: WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS\bin
Then continue with Vano Maisuradze answer
I think the problem is that you need to add the key to the machine's certificate store.
Application Pool Identity accounts don't have access to the certificate store by default.
Either you change to Network Services account as pointed by Vaibhav.Inspired or you give access to the certificate.
To allow access do the following command:
WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "IssuedToName" -a
"AccountName"
Notes:
- The tool may need to be installed first. The setup will place the tool at `C:\Program Files (x86)\Windows Resource Kits\Tools\WinHttpCertCfg.exe`.
- `IssuedName` is the issuer property of the certificate that the application will attempt to access
- The command must be run from command prompt with elevated privileges
Reference :https://support.microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica Step 2
Also you need to enable the Mark this key as exportable option when installing the certificate.
couple of troubleshooting steps:
Run your program as Administrator
If it is web app deployed in IIS -> then add the IIS_IUSRS to the Certificate permissions. Select certificate in Personal, Right Click-> Manage Private Keys -> Add the user.
Run Visual Studio in Admin mode if in Debug to get this problem sorted out
If you are able to debug the application, try running the IDE on admin mode..you can also add new users from MMC.
For local development, make sure the user has permissions to access the certificate, especially if you're installing it in the Local Machine store.
Open certificate manager (mmc.exe or certlm)
Go to certificate
Right Click > All Tasks > Manage Private Keys
Assign permission for current user
Done
This was the case for me when debugging it using Rider.
I had the same issue on c# console application and after reading answeres here I thought that problem was in permissions. Then I run visual studio as administrator and it worked.