当我遇到这种非常奇怪的行为时,我正在做一些测试……我不完全理解。
首先,我使用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”的证书,并且该证书具有私钥。
查看权限(“所有任务”>“管理私钥...”),您会看到该密钥对管理员可用,但对“普通”用户不可用。
接下来,我执行了我的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文件后,密钥存储区允许我访问证书的私钥?