Install Certificate in IIS CurrentUser/Personal Store - azure

We are hosting some websites on azure and some on a vm in azure. We want to reuse as much code as possible. In azure application services (websites) the installed certificates can be found in the CurrentUser/Personal store using this snippet:
using (var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
certStore.Open(OpenFlags.ReadOnly);
var certCollection =
certStore.Certificates.Find(
X509FindType.FindByThumbprint,
thumbprint,
false);
}
I want to use the exact same snippet on IIS as well. The application pool identity is set to ApplicationPoolIdentity. I already tried to install the certificate in various places but I am not able to retrieve the desired certificate ... I have also tried to install the certificate in the LocalComputer/Personal store and grant permissions to the private key
Which Identity shall I use in the MMC Snap-In? I cannot find the ApplicationPoolIdentity user account there. There is only an Application Identity account which does not solve my issue ...

If you wanted to use the Local Computer store instead of the personal store of a named user you would need to use StoreLocation.LocalMachine in your call to the X509Store constructor, the Enum consists of two values and in your code above you're using the other - CurrentUser. If you are using the certificate's private key the IIS AppUser\ApplicationPoolIdentity user would need access to the relevant certificates in the Local Computer store, this can be granted by adding the DefaultAppPool user to the allowed users in the relevant certificate's private key permissions dialog. This is accessible from the certificate's context menu, under All Tasks and then Manage Private Keys.
I am not currently sure if it is possible to install certificates for the ApplicationPoolIdentity user, I'm currently trying to find the answer to this myself. According to Microsoft's IIS documentation the ApplicationPoolIdentity account is a virtual account created for the life of the pool, so I am starting to conclude it may not be possible to use the CurrentUser store for this type of user. If I find out definitively I will come back and update my answer.

For the time being I am creating a new user, adding the certificate to the users My store and using that user as app pool identity. Still, other solutions are very welcome!

Related

Blazor Hosted WebAssembly application with Identity Server fails in production

I am developping a Hosted Blazor WebAssembly application with Identity Server. It works perfectly in my development environment, but fails in a production environment.
To try and find the reason, I went back to the templates supplied with Visual Studio and got the same issue. So here are the details to replicate.
In VS 2022 (currently 17.4.4), create a new project.
Select the Blazor WebAssembly App template.
Select .NET 7.0 framework.
Select Individual Accounts for the Authentication type and check the ASP.NET Core Hosted option.
The application runs fine locally.
Before publishing it:
Create a self signed certificate with PowerShell and export it to a certificate.pfx file.
Edit the IdentityServer section in appsettings.json:
"IdentityServer": {
"key": {
"Type": "File",
"FilePath": "certificate.pfx",
"Password": "password"
},
"Clients": {
"BlazorWasmIdentityHosted.Client": {
"Profile": "IdentityServerSPA"
}
}
}
In Visual Studio, modify the certificate.pfx properties so that it is copied when publishing.
Modify the web.config file in the publish folder so that exception pages are displayed in the browser:
<aspNetCore ...>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
I then get an error page as soon as I request the home page
CryptographicException: File not found.
System.Security.Cryptography.X509Certificates.CertificatePal.FilterPFXStore(ReadOnlySpan<byte> rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
InvalidOperationException: There was an error loading the certificate. Either the password is incorrect or the process does not have permisions to store the key in the Keyset 'DefaultKeySet'
Microsoft.AspNetCore.ApiAuthorization.IdentityServer.SigningKeysLoader.LoadFromFile(string path, string password, X509KeyStorageFlags keyStorageFlags)
As I am deploying to a hosting provider where I don't have a direct access to IIS, I suspect that I don't have the rights to add an item to a certificate store.
I tried deploying to IIS on my local machine, it runs fine.
So, my question is: Is there any other way to manage a signing key in this specific configuration: IIS on a shared hosting provider (managed with Plesk)?
The Microsoft documentation gives details about deploying to Azure (here), but I didn't find much on deploying to IIS in my situation.
Edited:
I finally think the issue was with lack of access rights for the IIS user on the hosting provider. Not sure if that can be fixed (depends on the provider), so I finally moved to Azure. Setting and deploying need some care, but at least it's well documented by Microsoft, and now it works for me.
I recently came across an article discussing common issues when dealing with X509Certificate2 object creation, handling private key material in application code. One of the common problems is certificate and private key handling inside .NET applications. Most of the problems for these use cases occur in web applications when certificate lookup/instantiation fails. For example, certificate reading works on a developer machine, but fails when the application is deployed to production. I want to share the content of this article with you, in order to avoid the article link from expiring, I quoted the content from the article in the answer, hoping to bring you some help.
There are two common deployment models for application certificates:
Persistent - certificate is installed in certificate store which is independent to application (such as Windows Certificate Store). The installed certificate is shared with any other application that runs under same security account.
In-app - The certificate is either embedded in the app itself or
stored as an external protected file. This includes PFX files,
keychains, Azure Key Vault, and many others.
Pros and Cons of the Persistent Deployment Model:
The benefit of the persistent deployment model is simplified
certificate management, which can be easily installed and managed
using external mechanisms such as certificate autoenrollment and
Certificate Lifecycle Manager (CLM). CLM makes it easy to manage
certificates in the certificate store without having to update or
redeploy applications every time certificates are renewed.
Of course the downside of this mode is that there is no certificate
isolation/protection between processes. When the application is
deleted, the certificate is not deleted and remains on the system.
Even if the certificate is deleted from persistent storage (Windows
certificate store), the private key is not necessarily deleted: case
of accidental deletion of user certificates. Another process under the
same security account or a computer administrator can easily access
the certificate and its private key material.
The in-app deployment model has the opposite characteristics of the persistent model.
The benefit of the in-app model is better certificate and private key
security. Private keys may not be shared with other applications
running under the same security account, and computer administrators
may be prevented from accessing private key material. The application
loads the certificate into memory only when necessary, and then
unloads the certificate and private key.
There is a parameter called password which is known only to authorized
applications and which provides private key isolation between
processes. Applications that do not know the password can’t access the
certificate and private key. Although the code looks secure, in fact
it is not in the current way. The problem is with default behavior of
the X509Certificate2 constructors that import certificate from PFX.
Using default constructors, such as X509Certificate2(String, String),
X509Certificate2(String, SecureString), X509Certificate2(Byte[],
String), X509Certificate2(Byte[], SecureString), private key is
silently copied and persisted on a system, this will introduce
security holes in working code. Any simple application/script can use
FileSystemWatcher to detect key file creation and immediately create a
copy of the key file.
To avoid this bad behavior, a constructor with three parameters must
be used. The third parameter is the X509KeyStorageFlags enumeration
type.
DefaultKeySet — copies private key to default store. It can be specified in PFX properties (user key set or machine key set). If none
specified in PFX, user key set is used. This is something you don’t
want to use, because it persists the key on a disc. And if PFX
specifies Machine Key Set and application doesn’t have local
administrator/system permissions, the call will fail with exception.
UserKeySet — forces private key copy to user profile regardless what is specified in PFX properties.
MachineKeySet — forces private key copy to local system profile. If application doesn’t have local administrator/system permissions,
the call will immediately fail.
Exportable — copies private key to default key set (see rules above) and makes private key exportable. This makes zero sense,
because application doesn’t need to have an access to private key
material. If the application require this, the application is simply
wrong. Instead, the application must deal with handles provided by
operating system. Nothing else.
UserProtected — this flag enables private key strong protection. This doesn’t work with any non-interactive applications, because raise
UI popups and require user input. And in web/background applications
the popup is raised in background sessions you cannot access.
PersistKeySet — is similar to DefaultKeySet with the exception that private key permanently persists on a disk even if you explicitly
release all handles.
EphemeralKeySet — the only flag that doesn’t copy private key material on a disk and the only that makes sense, because it does
exactly what we need — temporarily load the key from PFX and unload
when finished.
When loading a certificate with a private key from PFX or Azure Key Vault, you >should use the EphemeralKeySet enumeration value.
For more detailed content, you can get an in-depth understanding through the article link provided above.

How do you setup and retrieve encryption and signing certificates in IIS for OpenIddict?

I am new to OpenIddict and authorization in general. I am having trouble storing and retrieving the encryption and signing certificates that will be used by OpenIddict. I will be deploying this as a production-ready app to IIS.
I would like to know how I would go about storing the certificates in IIS and then retrieving them in my app startup?
Here are the two methods I need to use in Startup.ConfigureServices:
options.AddEncryptionCertificate();
options.AddSigningCertificate();
I created both of these certificates manually using this code, then writing them to .pfx files.
I then used the certificate import wizard to import the certificates to my host computer that is running IIS. But right now I am confused on how to retrieve these certificates from IIS storage when calling options.Add_Certificate(). Right now I can retrieve the certificate directly from the project folder but this seems quite unsafe to have the certificates sitting in the folder.
Thank you
You can use this code get list of certificate.
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 certificate in store.Certificates){
//TODO's
}
Then you can add certificate in the foreach.

Azure Cloud configuration in c#

I am trying to read Azure Configuration values and I also followed the answer provided in
Read configuration settings from azure cloud service with .NET C#
I want to know from where I can get the following parameter values:
subscriptionId
thumbprint
StoreLocation.CurrentUser
StoreLocation.LocalMachine
X509Store store = new X509Store("My", location) -- what i need to write at the place of "My"
-- what i need to write at the place of "My"
You also need to use My. For more information please refer to What are the Windows system certificate stores?
Each of the three stores contain a number of folders which certificates go into
Personal (can be known as My when using scripts to add certs)
Trusted Root Certification Authority (can be known as Root)
Enterprise Trust
Intermediate Certification Authority
Active Directory User Object
Trusted Publishers
Untrusted Certificates
Third Party Root Certification Authorities
Trusted People
We could get the subscriptionId from Azure portal, details please refer to this document.
About thumbprint please refer to How to: Retrieve the Thumbprint of a Certificate
StoreLocation.CurrentUser and StoreLocation.LocalMachine is StoreLocation Enum

What certificate store should I use to store a certificate for signing/encrypting JWT tokens?

I'm adding support for JWT tokens in my Web Application, and I have an X509 certificate which it needs for signing those tokens.
I have rejected the idea of using the same certificate we use for HTTPs (see Can I use the Private Key Certificate of Web App to sign JWT?).
I think a self signed certificate should do the trick, in fact I can't see any advantages of a web of trust in this scenario (that doesn't mean there aren't any, I just can't think of any).
The web application runs on a farm of web servers. My current plan is to generate a self signed cert and put the X509 certificate into the certificate store in Windows on each machine. Our IT department are checking, but they think they can roll that out to all the Web Servers in the farm using Group Policy. So this seems like a feasible plan.
The certificate store in windows looks pretty confusing to me. I think there are two options:
1) Put it in "My" store for the user under which the IIS App pool run. There are many app pools, so potentially the certificate will be in many stores.
2) Put it under the LocalMachine store, and then grant explicit access to the specific certificate for the IIS user(s).
3) Something else I can't think of.
Is there a "correct" place for these type of certs, and if so where is it?
The usual CertificateStore for signing certificates is the My store. I normally place them in LocalMachine location, but it is probably safer to put them in the certificate store for the Application Pool identity itself.
I would then give the Application Pool read-only access to this certificate only (right click certificate, then 'All Tasks' > 'Manage Private Keys', then add your Application Pool identity and give 'Read' permissions only.

how to add certificate and keys and service identities in windows azure?

I am developing one asp.net website and I will be hosting the site on windows azure. My requirement is when user access the site like www.xyz.com\admin then live id authentication should happen but when the user access the site www.xyz.com then no need do authentication.
After referring to an MSDN document I come to know about ACS with WIF, so I created the namespace and did so on so on.
But whenever I am accessing the federation URL (https://xyz.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml) I am getting error:
ID:1089 unable to connect the remote server.
I unfortunately deleted the certificate and keys and service identities in windows azure I don't know how to get it back, also I don't how do fulfill my requirement.
If you deleted the certificates and keys they all you need is to just create new one(s). You can either use Self Signed certificates, or use X.509 certificates issued by a trusted Certificate Authority. Once you get your X.509 certificate (it shall include a private key) you can upload it in the ACS management portal (which is locate at https://xyz.accesscontrol.windows.net/):
The FederationMedatadata.xml cannot be generated without the Token Signing certificate.
Or, the easiest for you, would be to just delete that namespace and create a new one.

Resources