密钥库中的证书包含私钥-即使用户没有访问权限

时间:2019-01-16 10:19:36

标签: c# powershell .net-core certificate x509certificate

当我遇到这种非常奇怪的行为时,我正在做一些测试……我不完全理解。

首先,我使用Powershell创建了一个自签名证书:

# Creates a certificate and adds it to the certificate store (private key included)
$certInfo = New-SelfSignedCertificate -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(300) -Subject "MyTestCert" -DnsName "localhost" -KeyAlgorithm "RSA" -KeyLength 2048 -HashAlgorithm "SHA256" -CertStoreLocation "Cert:\LocalMachine\My" -FriendlyName "MyTestCert" 

Write-Host "Created cert: $($certInfo.Subject) - $($certInfo.Thumbprint)"

# Exports the certificate as pfx (private key included)
$PFXPass = ConvertTo-SecureString -String "123456" -Force -AsPlainText
Export-PfxCertificate -Cert "cert:\LocalMachine\My\$($certInfo.Thumbprint)" -Password $PFXPass -FilePath "C:\Temp\$($certInfo.Subject.SubString(3)).pfx"

这将成功创建主题为“ MyTestCert”的证书,并且该证书具有私钥。

Windows key store

查看权限(“所有任务”>“管理私钥...”),您会看到该密钥对管理员可用,但对“普通”用户不可用。

Manage private keys

接下来,我执行了我的C#代码(.NET core 2.2)(VS调试,在没有管理员特权的情况下运行),该代码从存储中读取证书并尝试使用证书私钥:

internal class Program
{
   private static X509Certificate2 GetCertFromFile()
   {
       const String certFileName = @"C:\Temp\MyTestCert.pfx";
       var cert = new X509Certificate2( certFileName, "123456", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet );
       return cert;
   }

   private static X509Certificate2 GetCertFromStore()
   {
       using ( var store = new X509Store( StoreName.My, StoreLocation.LocalMachine ) )
       {
           store.Open( OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly );

           var matchingCerts = store.Certificates.Find( X509FindType.FindBySubjectName, "MyTestCert", false );
           return matchingCerts[0];
       }
   }

   private static void Main( String[] args )
   {
       var certificate = GetCertFromStore();

       // Does throw exception "Keyset does not exist"
       try
       {
           var rsa = certificate.GetRSAPrivateKey();
       }
       catch ( CryptographicException ex )
       {
           Console.WriteLine( ex );
       }

       certificate = GetCertFromFile();
       // This will work
       var rsa1 = certificate.GetRSAPrivateKey();

       Console.ReadLine();
   }
}

按预期,从存储区(GetCertFromFile)加载的证书不包含私钥。 (以管理员身份执行时,证书包含私钥。) 从PFX文件(GetCertFromFile)加载的证书确实包含一个私钥。

现在是奇怪的部分。

当我第二次执行该应用程序时,从商店(GetCertFromFile)加载的证书确实包含私钥。

为什么在我读取PFX文件后,密钥存储区允许我访问证书的私钥?

0 个答案:

没有答案