Как установить разрешение на чтение файла закрытого ключа сертификата X.509 из .NET - PullRequest
28 голосов
/ 08 января 2009

Вот код для добавления 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 на доступ к закрытому ключу.

Может кто-нибудь пролить свет? Заранее спасибо.

Ответы [ 5 ]

41 голосов
/ 04 февраля 2011

Этот ответ опоздал, но я хотел опубликовать его для всех, кто ищет здесь:

Я нашел статью в блоге MSDN, в которой предлагалось решение с использованием CryptoKeySecurity здесь , а вот пример решения на 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 будет работать так же хорошо.

16 голосов
/ 02 июля 2015

Если это кому-нибудь поможет, я написал ответ Джима Флуда в Powershell

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

16 голосов
/ 09 января 2009

Чтобы сделать это программно, вам нужно сделать три вещи:

  1. Получить путь к папке с секретным ключом.

  2. Получить имя файла закрытого ключа в этой папке.

  3. Добавить разрешение для этого файла.

См. этот пост для примера кода, который выполняет все три (в частности, посмотрите на метод "AddAccessToCertificate").

11 голосов
/ 09 января 2009

Вы можете использовать WinHttpCertCfg.exe инструмент , который поставляется как часть Windows Server 2003 Resource Kit Tools .

Пример:

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


В качестве альтернативы вы можете использовать инструмент Поиск закрытого ключа , который поставляется вместе с WCF SDK, чтобы найти местоположение на диске файла закрытого ключа сертификата. Затем вы можете просто использовать ACL для установки правильных прав доступа к файлу.

Пример:

FindPrivateKey My LocalMachine -n "CN=test"
3 голосов
/ 03 октября 2012

Это решение, которое я нашел для Windows Server 2008, если кому-то было интересно: http://technet.microsoft.com/en-us/library/ee662329.aspx

По сути, мне пришлось предоставить разрешения службе, которой требуется доступ к сертификату с помощью инструмента MMC. Работает как шарм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...