จะให้ ASP.NET เข้าถึงคีย์ส่วนตัวในใบรับรองในที่เก็บใบรับรองได้อย่างไร


111

ฉันมีแอปพลิเคชัน ASP.NET ที่เข้าถึงคีย์ส่วนตัวในใบรับรองในที่เก็บใบรับรอง ใน Windows Server 2003 ฉันสามารถใช้ winhttpcertcfg.exe เพื่อให้การเข้าถึงคีย์ส่วนตัวไปยังบัญชี NETWORK SERVICE ฉันจะให้สิทธิ์ในการเข้าถึงคีย์ส่วนตัวในใบรับรองในที่เก็บใบรับรอง (Local Computer \ Personal) บน Windows Server 2008 R2 ในเว็บไซต์ IIS 7.5 ได้อย่างไร

ฉันได้ลองให้สิทธิ์เข้าถึง "ทุกคน", "IIS AppPool \ DefaultAppPool", "IIS_IUSRS" และบัญชีความปลอดภัยอื่น ๆ ที่ฉันพบได้โดยใช้ใบรับรอง MMC (Server 2008 R2) อย่างไรก็ตามรหัสด้านล่างนี้แสดงให้เห็นว่ารหัสไม่สามารถเข้าถึงคีย์ส่วนตัวของใบรับรองที่นำเข้ามาพร้อมกับคีย์ส่วนตัว รหัสจะแสดงข้อผิดพลาดแทนทุกครั้งที่มีการเข้าถึงคุณสมบัติคีย์ส่วนตัว

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="repeater1" runat="server">
            <HeaderTemplate>
                <table>
                    <tr>
                        <td>
                            Cert
                        </td>
                        <td>
                            Public Key
                        </td>
                        <td>
                            Private Key
                        </td>
                    </tr>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).GetNameInfo(X509NameType.SimpleName, false) %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPublicKeyAccess() %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPrivateKeyAccess() %>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table></FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Web.UI;
public partial class _Default : Page 
{
    public X509Certificate2Collection Certificates;
    protected void Page_Load(object sender, EventArgs e)
    {
        // Local Computer\Personal
        var store = new X509Store(StoreLocation.LocalMachine);
        // create and open store for read-only access
        store.Open(OpenFlags.ReadOnly);
        Certificates = store.Certificates;
        repeater1.DataSource = Certificates;
        repeater1.DataBind();
    }
}
public static class Extensions
{
    public static string HasPublicKeyAccess(this X509Certificate2 cert)
    {
        try
        {
            AsymmetricAlgorithm algorithm = cert.PublicKey.Key;
        }
        catch (Exception ex)
        {
            return "No";
        }
        return "Yes";
    }
    public static string HasPrivateKeyAccess(this X509Certificate2 cert)
    {
        try
        {
            string algorithm = cert.PrivateKey.KeyExchangeAlgorithm;
        }
        catch (Exception ex)
        {
            return "No";
        }
        return "Yes";
    }
}

คำตอบ:


195
  1. สร้าง / ซื้อใบรับรอง ตรวจสอบว่ามีคีย์ส่วนตัว
  2. นำเข้าใบรับรองไปยังบัญชี "Local Computer" ควรใช้ใบรับรอง MMC อย่าลืมเลือก "อนุญาตให้ส่งออกคีย์ส่วนตัว"
  3. ตามที่ระบุข้อมูลประจำตัวของ IIS 7.5 Application Pool ใช้อย่างใดอย่างหนึ่งต่อไปนี้

    • เว็บไซต์ IIS 7.5 ทำงานภายใต้ ApplicationPoolIdentity เปิด MMC => เพิ่มใบรับรอง (ภายในเครื่องคอมพิวเตอร์) snap-in => ใบรับรอง (ภายในเครื่องคอมพิวเตอร์) => ส่วนบุคคล => ใบรับรอง => คลิกขวาใบรับรองที่น่าสนใจ => งานทั้งหมด => จัดการคีย์ส่วนตัว => เพิ่มและให้มันIIS AppPool\AppPoolName Full controlแทนที่ " AppPoolName " ด้วยชื่อพูลแอปพลิเคชันของคุณ (บางครั้งIIS_IUSRS)
    • เว็บไซต์ IIS 7.5 ทำงานภายใต้ NETWORK SERVICE การใช้ใบรับรอง MMC เพิ่ม "NETWORK SERVICE" เพื่อความน่าเชื่อถือเต็มรูปแบบในใบรับรองใน "Local Computer \ Personal"
    • เว็บไซต์ IIS 7.5 ทำงานภายใต้บัญชีผู้ใช้คอมพิวเตอร์ภายใน "MyIISUser" การใช้ใบรับรอง MMC เพิ่ม "MyIISUser" (บัญชีผู้ใช้คอมพิวเตอร์ภายในเครื่องใหม่) ในใบรับรองเต็มความน่าเชื่อถือใน "Local Computer \ Personal"

อัปเดตตามความคิดเห็นของ @Phil Hale:

ระวังถ้าคุณอยู่ในโดเมนโดเมนของคุณจะถูกเลือกโดยค่าเริ่มต้นในกล่อง "จากตำแหน่งที่ตั้ง" อย่าลืมเปลี่ยนเป็น "Local Computer" เปลี่ยนตำแหน่งเป็น "Local Computer" เพื่อดูข้อมูลประจำตัวของแอปพูล


3
วิธีกำหนดค่า ("XXX" เป็น Full Trust บนใบรับรองใน "Local Computer \ Personal") ใน Windows Server 2008 R2 เรียกใช้ / mmc / ไฟล์ / เพิ่มสแนปอิน / ใบรับรองและ ??? ขอบคุณ
Cobaia

7
เมื่อคุณเปิดใบรับรอง MMC ไปยัง Local Computer \ Personal ให้คลิกที่ "ใบรับรอง" เพื่อดูใบรับรอง (หมายเหตุ: ต่อไปนี้จะถือว่าใบรับรองถูกนำเข้าแล้วหากไม่ได้นำเข้าใบรับรองก่อน) คลิกขวาที่ใบรับรองที่คุณต้องการให้สิทธิ์การควบคุมทั้งหมด ในเมนูบริบทคลิก "งานทั้งหมด" จากนั้นในเมนูย่อยให้คลิกที่ "จัดการคีย์ส่วนตัว" จากนั้นคุณสามารถเพิ่มผู้ใช้รายใดก็ได้ที่คุณต้องการให้ 'อ่าน' เข้าถึงคีย์ส่วนตัวสำหรับใบรับรอง
เธมส์

5
ตรวจสอบให้แน่ใจว่าได้เลือกคอมพิวเตอร์เฉพาะที่ในช่อง "จากตำแหน่งที่ตั้ง" สิ่งนี้ทำให้ฉันนิ่งงันไปชั่วขณะ โดเมนถูกเลือกโดยค่าเริ่มต้นดังนั้นจึงไม่พบผู้ใช้ข้อมูลประจำตัวพูลแอปจนกว่าฉันจะเปลี่ยนตำแหน่งเป็นคอมพิวเตอร์ในระบบ
Phil Hale

3
ใน Windows 2012 R2 EC2 VM ของ AWS (ใช้ IIS 8) คุณต้องให้IIS_IUSRSสิทธิ์เข้าถึงคีย์ส่วนตัวของใบรับรอง
DeepSpace101

4
มีความคิดอย่างไรที่จะทำสิ่งนี้ผ่าน powershell?
sonjz

43

หมายเหตุเกี่ยวกับการให้สิทธิ์ผ่าน MMC, Certs, Select Cert คลิกขวางานทั้งหมด "Manage Private Keys"

จัดการคีย์ส่วนตัวอยู่ในรายการเมนูสำหรับส่วนบุคคลเท่านั้น ... ดังนั้นหากคุณใส่ใบรับรองใน Trusted People ฯลฯ คุณก็โชคไม่ดี

เราพบวิธีแก้ปัญหานี้ซึ่งเหมาะกับเรา ลากและวางใบรับรองเป็นส่วนบุคคลจัดการคีย์ส่วนตัวเพื่อให้สิทธิ์ อย่าลืมตั้งค่าให้ใช้บิวท์อินประเภทออบเจ็กต์และใช้เครื่องภายในที่ไม่ใช่โดเมน เราให้สิทธิ์แก่ผู้ใช้ DefaultAppPool และทิ้งไว้ที่นั้น

เมื่อคุณทำเสร็จแล้วให้ลากและวางใบรับรองกลับที่เดิมที่คุณเคยมี โอมเพี้ยง


ใช่มันใช้งานได้ดี ฉันพูดถึงคำตอบในโพสต์ต่อไปนี้อย่างไรก็ตามคำตอบอื่นได้รับการยอมรับแม้ว่าคำตอบที่ยอมรับจะยาวกว่ามากและต้องดาวน์โหลดไฟล์ WCF stackoverflow.com/questions/10580326/…
thames

2
โซลูชันใด ๆ สำหรับเซิร์ฟเวอร์ win2003? ไม่มี Manage Private Keys เป็นตัวเลือกเช่น windows 7
sonjz

1
@sonjz - ตรวจสอบเทคนิคนี้กล่าวถึงโดยใช้บรรทัดคำสั่งwinhttpcertcfg
mlhDev

หากคุณต้องการคีย์ส่วนตัวสำหรับใบรับรองสำหรับสิ่งใดก็ตามนอกจากส่วนตัวคุณมักจะทำอะไรผิดพลาด ... ตำแหน่งอื่น ๆ ทั้งหมดมีไว้สำหรับหน่วยงานอื่น / ภายนอกที่คุณเชื่อถือ คุณไม่ควรมีคีย์ส่วนตัว กุญแจสาธารณะ (ใบรับรอง) ของพวกเขาก็น่าจะเพียงพอแล้ว ฉันยังกล้าพูดเลยว่าถ้าคุณมีกุญแจส่วนตัวก็ไม่ควรไว้วางใจพวกเขา
Martin

15

หากคุณกำลังพยายามโหลดใบรับรองจากไฟล์. pfx ใน IIS วิธีแก้ปัญหาอาจทำได้ง่ายเพียงแค่เปิดใช้งานตัวเลือกนี้สำหรับไฟล์Application Pool.

คลิกขวาบน App Advanced Settingsสระว่ายน้ำและเลือก

จากนั้นเปิดใช้งาน Load User Profile


ใส่คำอธิบายภาพที่นี่


1
เหตุใดสิ่งนี้จึงสร้างความแตกต่าง
MichaelD

3
มันต้องเป็นวิธีที่ windows ต่อสาย อาจเป็นการโหลดโปรไฟล์ลงในโปรไฟล์ผู้ใช้ชั่วคราวดังนั้นจึงต้องใช้ตัวเลือกนี้ ฉันยอมรับว่ามันแปลกที่สิ่งนี้จำเป็นเมื่อโหลดจากไฟล์ที่ IIS สามารถเข้าถึงได้
Simon_Weaver

สิ่งนี้ช่วยฉันเมื่อฉันตั้งค่าลายเซ็นดิจิทัลสำหรับ PDF
Fred Wilson

7

ฉันหาวิธีทำใน Powershell ที่มีคนถามเกี่ยวกับ:

$keyname=(((gci cert:\LocalMachine\my | ? {$_.thumbprint -like $thumbprint}).PrivateKey).CspKeyContainerInfo).UniqueKeyContainerName
$keypath = $env:ProgramData + \Microsoft\Crypto\RSA\MachineKeys\”
$fullpath=$keypath+$keyname

$Acl = Get-Acl $fullpath
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS AppPool\$iisAppPoolName", "Read", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl $fullpath $Acl

6

สำหรับฉันมันไม่มีอะไรมากไปกว่าการนำเข้าใบรับรองอีกครั้งโดยเลือก "อนุญาตให้ส่งออกคีย์ส่วนตัว"

ฉันเดาว่าจำเป็น แต่มันทำให้ฉันกังวลเพราะเป็นแอพของบุคคลที่สามที่เข้าถึงใบรับรองนี้


ขอบคุณฉันทำแบบนี้ X509Certificate2 cert = X509Certificate2 ใหม่ (certBytes, รหัสผ่าน, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
Juan Lozoya

1

การเติมเต็มคำตอบนี้เป็นแนวทางในการค้นหาคีย์ส่วนตัวของใบรับรองและเพิ่มสิทธิ์

นี่คือคำแนะนำในการรับFindPrivateKey.exe ที่พบในคู่มือสำหรับค้นหาคีย์ส่วนตัวของใบรับรอง


0

แม้ว่าฉันจะได้เข้าร่วมข้างต้น แต่ฉันก็มาถึงจุดนี้หลังจากพยายามหลายครั้ง 1- หากคุณต้องการเข้าถึงใบรับรองจากร้านค้าคุณสามารถทำได้ดังตัวอย่าง 2- การผลิตใบรับรองนั้นง่ายและสะอาดกว่ามากและใช้ผ่านเส้นทาง

Asp.net Core 2.2 OR1:

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace Tursys.Pool.Storage.Api.Utility
{
    class CertificateManager
    {
        public static X509Certificate2 GetCertificate(string caller)
        {
            AsymmetricKeyParameter caPrivateKey = null;
            X509Certificate2 clientCert;
            X509Certificate2 serverCert;

            clientCert = GetCertificateIfExist("CN=127.0.0.1", StoreName.My, StoreLocation.LocalMachine);
            serverCert = GetCertificateIfExist("CN=MyROOTCA", StoreName.Root, StoreLocation.LocalMachine);
            if (clientCert == null || serverCert == null)
            {
                var caCert = GenerateCACertificate("CN=MyROOTCA", ref caPrivateKey);
                addCertToStore(caCert, StoreName.Root, StoreLocation.LocalMachine);

                clientCert = GenerateSelfSignedCertificate("CN=127.0.0.1", "CN=MyROOTCA", caPrivateKey);
                var p12 = clientCert.Export(X509ContentType.Pfx);

                addCertToStore(new X509Certificate2(p12, (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet), StoreName.My, StoreLocation.LocalMachine);
            }

            if (caller == "client")
                return clientCert;

            return serverCert;
        }

        public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);

            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            //const string signatureAlgorithm = "SHA256WithRSA";
            //certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

            // Issuer and Subject Name
            X509Name subjectDN = new X509Name(subjectName);
            X509Name issuerDN = new X509Name(issuerName);
            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

            // Valid For
            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter = notBefore.AddYears(2);

            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);

            // Subject Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);
            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);


            // correcponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


            // merge into X509Certificate2
            X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKeyAlgorithm.GetDerEncoded());
            if (seq.Count != 9)
            {
                //throw new PemException("malformed sequence in RSA private key");
            }

            RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(info.ParsePrivateKey());
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            try
            {
                var rsap = DotNetUtilities.ToRSA(rsaparams);
                x509 = x509.CopyWithPrivateKey(rsap);

                //x509.PrivateKey = ToDotNetKey(rsaparams);
            }
            catch(Exception ex)
            {
                ;
            }
            //x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            return x509;

        }

        public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
        {
            var cspParams = new CspParameters
            {
                KeyContainerName = Guid.NewGuid().ToString(),
                KeyNumber = (int)KeyNumber.Exchange,
                Flags = CspProviderFlags.UseMachineKeyStore
            };

            var rsaProvider = new RSACryptoServiceProvider(cspParams);
            var parameters = new RSAParameters
            {
                Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
                P = privateKey.P.ToByteArrayUnsigned(),
                Q = privateKey.Q.ToByteArrayUnsigned(),
                DP = privateKey.DP.ToByteArrayUnsigned(),
                DQ = privateKey.DQ.ToByteArrayUnsigned(),
                InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
                D = privateKey.Exponent.ToByteArrayUnsigned(),
                Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
            };

            rsaProvider.ImportParameters(parameters);
            return rsaProvider;
        }

        public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);

            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            //const string signatureAlgorithm = "SHA256WithRSA";
            //certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

            // Issuer and Subject Name
            X509Name subjectDN = new X509Name(subjectName);
            X509Name issuerDN = subjectDN;
            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

            // Valid For
            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter = notBefore.AddYears(2);

            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);

            // Subject Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

            // selfsign certificate
            //Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);

            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);
            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);


            X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            CaPrivateKey = issuerKeyPair.Private;

            return x509;
            //return issuerKeyPair.Private;

        }

        public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
        {
            bool bRet = false;

            try
            {
                X509Store store = new X509Store(st, sl);
                store.Open(OpenFlags.ReadWrite);
                store.Add(cert);

                store.Close();
            }
            catch
            {

            }

            return bRet;
        }

        protected internal static X509Certificate2 GetCertificateIfExist(string subjectName, StoreName store, StoreLocation location)
        {
            using (var certStore = new X509Store(store, location))
            {
                certStore.Open(OpenFlags.ReadOnly);
                var certCollection = certStore.Certificates.Find(
                                           X509FindType.FindBySubjectDistinguishedName, subjectName, false);
                X509Certificate2 certificate = null;
                if (certCollection.Count > 0)
                {
                    certificate = certCollection[0];
                }
                return certificate;
            }
        }

    }
}

หรือ 2:

    services.AddDataProtection()
//.PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys"))
.ProtectKeysWithCertificate(
        new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "clientCert.pfx"), "Password")
        )
.UnprotectKeysWithAnyCertificate(
        new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "clientCert.pfx"), "Password")
        );

0

ในแผงใบรับรองคลิกขวาที่ใบรับรอง -> งานทั้งหมด -> จัดการคีย์ส่วนตัว -> เพิ่มผู้ใช้ IIS_IUSRS ด้วยการควบคุมทั้งหมด

ในกรณีของฉันฉันไม่จำเป็นต้องติดตั้งใบรับรองของฉันโดยเลือกตัวเลือก "อนุญาตให้ส่งออกคีย์ส่วนตัว" เหมือนที่กล่าวไว้ในคำตอบอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.