Asp.net core keep using the expired certificate - c#

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.

Related

Trouble publishing ASP.NET project with Code First database to Azure - Permission

I cannot migrate my Code First database to Azure - Error hints at permission, but I can't figure out what's missing?
I have created an empty SQL-database in Azure
(I can publish the web site without the EF migration)
Connection string in appsettings.json (+Development+Production) - Startup: ConfigureServices - DbContext gets the right connectionstring
serviceDependencies points to the right connectionstring - Local to LocalSecretsFile and Web Deploy to AzureAppSettings
I have commented out the LocalDB connection though (and changed reference in ConfigureServices)
I haven't deleted old migrations
Azure: App Service - Configuration - Application Settings -> Connection string is set
Azure: SQL Server - Access control (Classic administrator): Service administrator (me) has full access
Azure: SQL Server - Firewalls and virtual networks: Client IP + App Inbound + 6 * App Outbound applied - 'Deny public network access' is not checked - Yes to 'Allow Azure services and resources ...'
When publishing:
(Also tried running Visual Studio as administrator)
I can Validate connection
'File Publish Options': I choose 'Remove additional files at Destination'
'Databases': 'NameofConnStr': Use this connection string at runtime
'Entity Framework Migrations': Apply this migration on publish
'Site Extensions Options': Tried both with and without this
(I do not use the Key Vault)
Result:
Publish Executing command: dotnet ef migrations script --no-build --idempotent --configuration Release --output "..."
Generating Entity Framework SQL scripts completed successfully
Adding sitemanifest (sitemanifest)
Adding Child sitemanifest
Error: Web deployment task failed. (Make sure the database connection string for the server is correct and that you have appropriate permission to access the database. (Web Deploy Provider is "dbFullSql").
Error details:Could not complete an operation with the specified provider ("dbFullSql") when connecting using the Web Management Service. This can occur if the server administrator has not authorized the user for this operation
Learn more for "ERROR_USER_NOT_AUTHORIZED_FOR_DBFULLSQL": Web Deploy error codes - Diagnosis: A non-administrative user attempted to perform an operation with a Web Deploy provider for which the user is not currently authorized
(Build succeeded, Publish failed)
What's missing?
Should I add a new migration (and delete the old ones)?
Is there some problem with commenting out the connection to LocalDb?
Is there some setting in Azure I missed?
Well I finally succeeded in migrating my database.
I upgraded Visual Studio 2019 from 16.11.13 to 16.11.14. That's probably not the reason why it worked, but I just note it because I'm not sure what made the difference.
If someone has the same problem I'll try to summarize what worked although I think I have tried the combinations below before:
Ran Visual Studio as admin
I deleted the previous migrations (made in LocalDB) and added a new
The connectionstring only had Data Source/Initial Catalog/User Id/Password - i.e. not MultipleActiveResultSets/Encrypt/TrustServerCertificate/Connection Timeout
I ignored KeyVault (and LocalDB) service dependencies
New Publishing Profile
Published the Web app first (without migration)
Chose Apply migration and published again
All seems straight forward so it's a bit of a mystery ?!

net::ERR_CERT_AUTHORITY_INVALID in ASP.NET Core

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.

Can't find .bin file generated by app inside docker container

I have a c#/mono app running inside a docker container, using the very cool Dokku.
The app allows for token authentication and saves the keys used to validate incoming tokens inside the folder /keyChain/keyChain.bin in the root folder of the app. The app generates this folder and file by itself when it soes not exists, usually after a fresh deploy and the first auth requests comes in.
I need to mount the keyChain folder as a docker volume so the keychain gets persisted between deploys and not all users sessions are expired, forcing all users to sign in again.
However, although the app runs fine and auth works, the keyChain folder and it's contents are nowhere to be found inside the app folder, inside the Docker container, so there is nothing to mount...
Running dokku run app-name ls /app shows the contents of the app but not the keyChain folder. Running dokku run app-name find /app -type f -name "keyChain.bin" to just look for the file that way yields no results either.
I am using the NancyFx framework for the app with the Nancy.Authentication.Token package.
I am not fully sure if this is a docker/dokku related issue, a c#/mono issue or NancyFx/Nancy.Authentication.Token issue. Remember, the apps WORKS, so the keyChain.bin file must be inside the container somewhere...
Any insight is appreciated :-).

asp.net MSDeployEnableWebConfigEncryptRule fail to encrypt web.config

I have added <MSDeployEnableWebConfigEncryptRule>true</MSDeployEnableWebConfigEncryptRule> to .pubxml file in order to encrypt web config file. However, when publishing, i got the following error. I do not know whether there is extra setting needed in the web.config file other than inserting <MSDeployEnableWebConfigEncryptRule>true</MSDeployEnableWebConfigEncryptRule> in .pubxml
Error:
Web deployment task failed.(Fail to encrypt destination web.config. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FAILED_TO_ENCRYPT_WEB_CONFIG.)
Note: #ERROR_FAILED_TO_ENCRYPT_WEB_CONFIG does not appears anywhere on the given link.
How could i resolve this error? (note: i do not wish to pre-encrypt the web.config file locally before publishing it)
The problem seem to be that MSDeployEnableWebConfigEncryptRule doesn't work with MVC project that have multiple web.config files. Typically MVC project has Views/Web.Config file. This seems like a bug with MSDeploy.
My Workaround is to have a post deployment powershell script to perform same command on the destination server. See http://www.iis.net/learn/publish/using-web-deploy/web-deploy-powershell-cmdlets
Powershell Script Sample:
Add-PSSnapin WDeploySnapin3.0
$cmd = '%windir%\Microsoft.NET\Framework\v4.0.30319\ASPNET_REGIIS.exe -{0} {1} "{2}"' -f 'pef', 'connectionStrings', $destinationFolder
New-WDPublishSettings -UserId $UserName -Password $Password -ComputerName $destination -AllowUntrusted -FileName server.publishsettings -AgentType MSDepSvc -Site $Website
Invoke-WDCommand -Command $cmd -DestinationPublishSettings server -Verbose
I was getting this same message too.
I looked in the Web Deployment logs in the Event Viewer > Microsoft Web Deploy. The Exception it was giving me was:
ERROR_FAILED_TO_ENCRYPT_WEB_CONFIG
Microsoft.Web.Deployment.DeploymentDetailedClientServerException: Failed to encrypt destination web.config: .... Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FAILED_TO_ENCRYPT_WEB_CONFIG. ---> System.Security.Cryptography.CryptographicException: Object already exists.
Googling this led me to this answer from "Just TFS": Release Management Agent not connecting
Which said "The Deployer user (\) does not have access to the crypto store. On the server where the deployment agent is installed, navigate to this folder %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys and give read/write access to \. – Just TFS Sep 3 '14 at 12:08"
So I attempted to give my MS Deployer user account read/write to that MachineKeys folder but it denied me access to do so. I ended up adding the deployer user account as a local Administrator and that did the trick.
Was able to deploy with it encrypting the web.config file successfully to the server.

X509Certificate - Keyset does not exist

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.

Categories

Resources