Как установить разрешение на чтение файла закрытого ключа сертификата X.509 из .NET.
Вот код для добавления 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.
Может ли кто-нибудь пролить свет? Заранее спасибо.
- Как сообщить `ссылкам` игнорировать истекший SSL-сертификат и продолжить?
- Что мне нужно сделать, чтобы заставить Internet Explorer 8 принять самоподписанный сертификат?
- Как сказать Maven игнорировать ошибки SSL (и доверять всем сертификатам)?
- Подписанный SSL-сертификат третьей стороны для localhost или 127.0.0.1?
- Можно ли динамически вернуть сертификат SSL в NodeJS?
- Вызывается: java.security.UnrecoverableKeyException: невозможно восстановить ключ
- Не удалось загрузить ресурс: net :: ERR_INSECURE_RESPONSE
- Программно создавать сертификат X509 с использованием OpenSSL
- Почему запросы Python игнорируют параметр проверки?
- ошибка получения: «Ошибка: ошибка SSL: SELF_SIGNED_CERT_IN_CHAIN» при использовании npm
- Возможно ли иметь сертификат SSL для IP-адреса, а не доменное имя?
- Java7 Отказ от доверия сертификату в хранилище доверия
- Java: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификации для запрошенной цели
Чтобы сделать это программно, вам нужно сделать три вещи:
-
Получить путь к папке с закрытым ключом.
-
Получить имя файла закрытого ключа в этой папке.
-
Добавьте разрешение на этот файл.
См. Это сообщение для некоторого примера кода, который выполняет все три (в частности, посмотрите на метод AddAccessToCertificate).
Этот ответ поздний, но я хотел опубликовать его для любого другого, кто приходит сюда:
Я нашел статью в блоге 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 будет работать так же хорошо.
В случае, если это поможет кому-то еще, я написал ответ Джима Флуда в 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() }
Обратите внимание, что параметр учетной записи может быть в форме «DOMAIN \ USER» (а не только в именах) – я тестировал это в своей среде и автоматически конвертировал его в соответствующий идентификатор SID
Вы можете использовать инструмент WinHttpCertCfg.exe, который поставляется как часть средств набора ресурсов Windows Server 2003 .
Пример:
winhttpcertcfg -g -c LOCAL_MACHINE\My -s test -a NetworkService
Кроме того, вы можете использовать инструмент « Найти частный ключ», который поставляется вместе с WCF SDK, чтобы найти местоположение на диске файла закрытого ключа сертификата. Затем вы можете просто использовать ACL для установки правильных прав в файле.
Пример:
FindPrivateKey My LocalMachine -n "CN=test"
Это решение, которое я нашел для Windows Server 2008, если кому-то было интересно: http://technet.microsoft.com/en-us/library/ee662329.aspx
В принципе, я должен был предоставить разрешения для службы, которая должна получить доступ к сертификату с помощью инструмента MMC. Работает как шарм.