The super detailed uses SSL two-way authentication. One article is enough

Tradition: https between projects is transmitted only after one-way SSL authentication;
This article: SSL two-way authentication between projects to prevent attackers from malicious damage;

The difference between one-way authentication and two-way authentication:

This article is divided into four chapters
Chapter 1: Briefly describes the role classification of the server website in SSL two-way authentication;
Chapter 2: describes the configuration and verification of the client certificate carried by a third party when accessing our Server API;
Chapter 3: describes the configuration required when the website on our server accesses the third-party Server API as a client, and the configuration and acquisition of local certificates;
Chapter 4: Brief description of reference sources;

1 Narration

The current system has two different roles regarding SSL two-way authentication:
1. The current system acts as a server (when a third party requests our service, it needs to carry the client certificate issued to them)
2. The current system is the client (when we request third-party services, we need to carry the client certificate issued to us)
3. (Both can be combined)
The following chapters respectively describe the above (1) and (2) in detail;

2 Current system as server

2.1 IIS Configuration

(1) Check "Accept" when only some API s require Client Certificate; (This article)

(2) When the entire Service must have a Client Certificate, check "Require SSL" –>"Must";

2.2 Related codes

2.2.1 Code verification fragments

The class of the following code inherits the properties and overrides the base class methods;

var reClient = context.Request.GetClientCertificate();

if (reClient == null)
    _logService.Error($"Client Certificate is null.");
    context.ErrorResult = new AuthenticationFailureResult($"Client Certificate is require.", context.Request, HttpStatusCode.BadRequest);

var x509 = new X509Certificate2(reClient);
var chain = new X509Chain(true);

chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;//Revocation check using online certificate revocation list (CRL)

if (chain.Build(x509))
    context.ErrorResult = new AuthenticationFailureResult($"Invalid Client Certificate.", context.Request, HttpStatusCode.BadRequest);
    _logService.Error("Invalid Client Certificate. chain: " + chain.ToString());
List<string> x509IssuerList = WC_X509_IssuerListString.Replace(" ","").Split(';').ToList();//Remove spaces, WC_ X509_ The IssuerListString variable is the certificate of which CNs are allowed as configured in the Appsetting.config file. The semicolon is used as the separator, and multiple CNs can be configured

if (!x509IssuerList.Contains(x509.Issuer.Replace(" ", "")))
    context.ErrorResult = new AuthenticationFailureResult($"", context.Request, HttpStatusCode.BadRequest);//Not return any message.
    _logService.Error("Appsetting.config not exit x509Issuer: " + x509.Issuer.ToString());

2.2.2 AppSetting.config Settings

Value is used to configure which CNs are allowed to connect; Multiple CNs are separated by semicolons (user-defined);

2.3 Configuration of Computer Management Console MMC

Win+R -->mmc, open the console; As shown in the figure, click "File" –>"Add/Remove Snap in";

Select "Certificate" in the item on the left, click "Add" in the middle, as shown in the figure below, select "My User Account", and click "Finish" after all other items are defaulted; Select "Computer Account" in the same way;
(1) For users, when they need to install "Client Certificate" on their personal computers, they only need to add "My User Account";
(2) For the server, you only need to add a "computer account";

As shown in the figure below, it is the main interface for configuring "Client Certificate" and "Server Certificate" respectively;

2.3.1 Configure Client Certificates Adding Client Certificates

Expand the "Certificate - Current User" node, right click "Person" ->"Certificate", select "All Tasks" ->"Import", click "Next", select "Client. pfx" file, click "Next" ->enter the "Password" of the file, and click "Next" by default until completion; At this time, the client certificate has been added; Adding a Client Certificate CA Issuing Center

Under the "Certificate - Current User" node, click "Trusted Root Certification Authority" –>"Certificate", right-click "All Tasks" –>"Import", click Next, select the ". cer" file, and click Next by default until completion; At this time, the CA issuing center of the client certificate has been added;
Note: If the CA issuing center of the client certificate is inconsistent with that of the server certificate, the CA issuing file (i.e.. cer file) of the server certificate needs to be uploaded here;

2.3.2 Configure Server Certificate Adding a Server Certificate

Select the "Server. pfx" file; Consistent with the operation steps in; Adding a Server Certificate CA Issuing Center

Consistent with the operation steps in 3.1.2; Note: If the CA issuing center of the client certificate is inconsistent with that of the server certificate, the CA issuing file (i.e.. cer file) of the client certificate needs to be uploaded here;

2.4 log records of IIS for two-way authentication

Log storage location: C: inetpub logs LogFiles. The last number of the folder corresponds to the ID column of the application in IIS, as shown in the figure;

2.4.1 AWS Log Record Example

Provide the correct client certificate (IIS Log):

Provide a self signed client certificate (IIS Log):

Client certificate is not provided (Log4net record of website)

---->[Client certificates is null]

When the relevant certificate is provided, but the CN is not configured in appsetting.config (Log4net record of website)

2.5 Precautions

2.5.1 Differences between LAN and remote website deployment When the website deploys LAN

The website deployed in the LAN can generate CA, server certificate and client certificate through the local computer;
The test results of two computers in the LAN: SSL two-way verification requirements in the requirements can be passed; When the website is deployed at the remote end

(1) When deploying at the remote end, you need to use a certificate issued by a third-party CA (which requires a certain fee), or you can try to search "Apply for a free computer certificate" online;
(2) The self signed certificate is not trusted at the remote end, so it will be intercepted by IIS. You can view the relevant interception 403 record in the IIS log (refer to 4.1);
(3) The load balancer will not transfer the certificate to another machine;

2.5.2 Postman Configuration Request Certificate

Postman configuration client certificate is shown in the figure below (this file is provided by a third party)

2.5.3 Difference from SSL two-way handshake on the http layer

Because the client certificate is verified through the program, the client certificate needs to be submitted at the same time when requesting the API (Postman needs to configure the client certificate and the PEM file of the CA, which can be downloaded through the website);
From the http level, it is not actually two-way authentication, so only one-way authentication can be seen through packet capturing, but in a sense, it is more strict two-way authentication, because the "code+appsetting.config file" restricts which CNs can pass; The http level does not filter specific CNs;

3 Current system as client

3.1 Mandatory documents

1. The client certificate. pfx file provided by a third party;
2. The secret key of the client certificate provided by a third party (clear text, do not expose it at will);

3.2 Method of obtaining client certificate by code

Note: If the certificate often expires, you can select the method of "Obtain the certificate through the file path" (Within 1 years.), which can avoid complicated configuration steps such as installing through MMC;

3.2.1 Obtain certificate through file path (not preferred)

Note: If the Log file record indicates that IIS has no permission, you can modify the access permission of the file by right clicking the property.

#region method 1: Get the Client Certificate through the path;
    string certificatePath = @"....\ClientCertificateFile.pfx";//Use a relative path or an absolute path,
    string certPassword = "******"; //Clear text password corresponding to the client certificate;

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3|SecurityProtocolType.Tls| (SecurityProtocolType)768|(SecurityProtocolType)3072|(SecurityProtocolType)0x300|(SecurityProtocolType)0xC00;//Set according to the enumeration in the current framework version;

    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;//Get or set the callback used to verify the server certificate, true or false according to the actual situation;

    //The clientCer object is the client certificate carried on the request
    X509Certificate2 clientCer = new X509Certificate2(certificatePath, certPassword, X509KeyStorageFlags.MachineKeySet|X509KeyStorageFlags.PersistKeySet|X509KeyStorageFlags.Exportable);
catch (Exception ex)
    logger.Error($"Get Client certificate Error : {ex}.");
    return null;

3.2.2 Obtain the certificate installed through MMC (preferred)

    #region mode 2: Installing Client Certificate through mmc

                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; //Get or set the callback used to verify the server certificate, true or false according to the actual situation;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)0x300 | (SecurityProtocolType)0xC00;
#if !DEBUG
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); //Search from the Client Certificate installed on the Local Computer// Cannot use CurrentUser
                X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);//Search from the Client Certificate installed by the current user of the computer; You can also use LocalMachine
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                X509Certificate2 clientCer;
                    //var clintCertificatesList = store.Certificates.Cast<X509Certificate2>().Select(c => c.Thumbprint).ToList();
                    //foreach (var VARIABLE in clintCertificatesList)
                        //logger.Info($" {VARIABLE}.");// Print fingerprints of all certificates in MMC through log4net for debugging;

                    //Do not use "store. Certificates. Find()" -->Poor performance
                    //Find By certificate thumbprint.
                    //Case must be omitted;
                    clientCer = store.Certificates.Cast<X509Certificate2>().FirstOrDefault(c => c.Thumbprint.Equals("***Certificate thumbprint***", StringComparison.OrdinalIgnoreCase)); //linq syntax, obtaining the specified certificate according to the certificate fingerprint
                    if (clientCer == null)
                        logger.Error($"Client certificate is null.");
                        return null;
                catch (Exception ex)
                    logger.Error($"Get Client certificate Error : {ex}.");
                    return null;


3.3 Configuration of MMC and IIS

3.3.1 MMC Install and Configure Client Certificate Permissions

Testing and implementation personnel: see Section 2.3 of this document to install the client certificate (only on the local computer -->Local Machine);
Developer: refer to Section 2.3 (Local Machine, Current User);

3.3.2 Configure Client Certificate and IIS Permissions

Introduction: Two methods are provided here. Based on the security considerations of the website, it is recommended to configure the access permissions of the client certificate through MMC; Configure the access rights of client certificates through MMC (preferred)

Win+R -->mmc, open the console; As shown in the figure, click File –>Add/Remove Snap in – Certificate – Local Computer; As shown in the figure below;

After finding the specified client certificate installed, "right-click" - "All Tasks" - "Manage Private Keys" ->click "Add" ->click "Advanced" ->click "Find Now", as shown in the list below;

Select "IIS_IUSERS" –>click OK, –>click OK –>"Apply" –>"OK" to finish Set role permissions of IIS program pool (non preferred)

It is not recommended to use this method to set (for the difference between built-in accounts, there is a reference link in Chapter 4);
Step: Open IIS Manager, find the program pool corresponding to the website –>Advanced Settings – Process Model –>Identity –>Local System –>OK;

4 Appendices and References

4.1 Chapter III Reference Information

1. Permission description of IIS application pool identity

2. IIS cannot read the local certificate (see the answer): Advanced Setting –>Process Model –>Identity IIS has low permissions by default, which can be changed to Networkservice (I think it is OK to change to LocalSystem here, but it is unsafe because of too high permissions).

Comments and questions are welcome;

Tags: ASP.NET SSL server

Posted by davemwohio on Sat, 24 Sep 2022 21:11:20 +0300