当前位置:  开发笔记 > 编程语言 > 正文

如何从.NET设置X.509证书的私钥文件的读取权限

如何解决《如何从.NET设置X.509证书的私钥文件的读取权限》经验,为你挑选了4个好方法。

以下是将pfx添加到Cert存储的代码.

X509Store store = new X509Store( StoreName.My, StoreLocation.LocalMachine );
store.Open( OpenFlags.ReadWrite );
X509Certificate2 cert = new X509Certificate2( "test.pfx", "password" );
store.Add( cert );
store.Close();

但是,我找不到为NetworkService设置访问私钥的权限的方法.

任何人都能解释一下吗?提前致谢.



1> Jim Flood..:

这个答案很晚,但我想把它发布给在这里搜索的其他人:

我发现,使用CryptoKeySecurity给了一个解决方案的MSDN博客文章在这里,并在这里是在C#中的解决方案的示例:

var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
if (rsa != null)
{
    // Modifying the CryptoKeySecurity of a new CspParameters and then instantiating
    // a new RSACryptoServiceProvider seems to be the trick to persist the access rule.
    // cf. http://blogs.msdn.com/b/cagatay/archive/2009/02/08/removing-acls-from-csp-key-containers.aspx
    var cspParams = new CspParameters(rsa.CspKeyContainerInfo.ProviderType, rsa.CspKeyContainerInfo.ProviderName, rsa.CspKeyContainerInfo.KeyContainerName)
    {
        Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore,
        CryptoKeySecurity = rsa.CspKeyContainerInfo.CryptoKeySecurity
    };

    cspParams.CryptoKeySecurity.AddAccessRule(new CryptoKeyAccessRule(sid, CryptoKeyRights.GenericRead, AccessControlType.Allow));

    using (var rsa2 = new RSACryptoServiceProvider(cspParams))
    {
        // Only created to persist the rule change in the CryptoKeySecurity
    }
}

我正在使用SecurityIdentifier来识别帐户,但NTAccount也可以正常工作.


我更喜欢这个解决方案,因为代码更少,不需要弄乱文件路径.
对于某些证书,我认为使用下一代加密技术(CNG)提供程序制作的证书,上面的代码找不到私钥。在这种情况下,这可能会有所帮助:/sf/ask/17360801/

2> 小智..:

如果这有助于其他人,我在Powershell写了Jim Flood的答案

function Set-PrivateKeyPermissions {
param(
[Parameter(Mandatory=$true)][string]$thumbprint,
[Parameter(Mandatory=$false)][string]$account = "NT AUTHORITY\NETWORK SERVICE"
)
#Open Certificate store and locate certificate based on provided thumbprint
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
$store.Open("ReadWrite")
$cert = $store.Certificates | where {$_.Thumbprint -eq $thumbprint}

#Create new CSP object based on existing certificate provider and key name
$csp = New-Object System.Security.Cryptography.CspParameters($cert.PrivateKey.CspKeyContainerInfo.ProviderType, $cert.PrivateKey.CspKeyContainerInfo.ProviderName, $cert.PrivateKey.CspKeyContainerInfo.KeyContainerName)

# Set flags and key security based on existing cert
$csp.Flags = "UseExistingKey","UseMachineKeyStore"
$csp.CryptoKeySecurity = $cert.PrivateKey.CspKeyContainerInfo.CryptoKeySecurity
$csp.KeyNumber = $cert.PrivateKey.CspKeyContainerInfo.KeyNumber

# Create new access rule - could use parameters for permissions, but I only needed GenericRead
$access = New-Object System.Security.AccessControl.CryptoKeyAccessRule($account,"GenericRead","Allow")
# Add access rule to CSP object
$csp.CryptoKeySecurity.AddAccessRule($access)

#Create new CryptoServiceProvider object which updates Key with CSP information created/modified above
$rsa2 = New-Object System.Security.Cryptography.RSACryptoServiceProvider($csp)

#Close certificate store
$store.Close()

}

请注意,account参数也可以采用"DOMAIN\USER"的形式(不仅仅是内置名称) - 我在我的环境中对此进行了测试,并自动将其转换为相应的SID



3> Eric Rosenbe..:

要以编程方式执行此操作,您必须执行以下三项操作:

    获取私钥文件夹的路径.

    获取该文件夹中私钥的文件名.

    将权限添加到该文件.

有关完成所有这三项操作的示例代码,请参阅此文章(特别是查看"AddAccessToCertificate"方法).



4> Enrico Campi..:

您可以使用作为Windows Server 2003 Resource Kit工具的一部分提供的WinHttpCertCfg.exe 工具.

例:

winhttpcertcfg -g -c LOCAL_MACHINE\My -s test -a NetworkService


或者,您可以使用WCF SDK附带的" 查找私钥"工具来查找证书私钥文件的磁盘位置.然后,您只需使用ACL即可为文件设置正确的权限.

例:

FindPrivateKey My LocalMachine -n "CN=test"

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有