Comment définir une autorisation de lecture sur le fichier de clé privée du certificat X.509 à partir de .NET

StackOverflow https://stackoverflow.com/questions/425688

  •  06-07-2019
  •  | 
  •  

Question

Voici le code pour ajouter un pfx au magasin de certificats.

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

Cependant, je n’ai pas trouvé de moyen de définir l’autorisation pour NetworkService d’accéder à la clé privée.

Quelqu'un peut-il nous éclairer? Merci d'avance.

Était-ce utile?

La solution

Pour le faire par programme, vous devez faire trois choses:

  1. Obtenir le chemin du dossier de la clé privée.

  2. Obtenez le nom de fichier de la clé privée dans ce dossier.

  3. Ajoutez l'autorisation à ce fichier.

Voir ce message pour un exemple de code qui fait les trois (regardez plus particulièrement la méthode "AddAccessToCertificate").

Autres conseils

Cette réponse a pris du retard, mais je voulais l’afficher pour tous ceux qui viennent chercher ici:

J'ai trouvé un article de blog MSDN qui proposait une solution utilisant CryptoKeySecurity ici , et voici un exemple de solution en 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
    }
}

J'utilise un identifiant de sécurité pour identifier le compte, mais un compte NTA fonctionnerait aussi bien.

Au cas où cela aiderait quelqu'un d'autre, j'ai écrit la réponse de Jim Flood dans 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 {

Au cas où cela aiderait quelqu'un d'autre, j'ai écrit la réponse de Jim Flood dans Powershell

<*>

Notez que le paramètre de compte peut être sous la forme "DOMAIN \ USER". ainsi (mais pas uniquement dans les noms intégrés) - j’ai testé cela dans mon environnement et l’a automatiquement converti en SID approprié

.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() }

Notez que le paramètre de compte peut être sous la forme "DOMAIN \ USER". ainsi (mais pas uniquement dans les noms intégrés) - j’ai testé cela dans mon environnement et l’a automatiquement converti en SID approprié

Vous pouvez utiliser l'outil WinHttpCertCfg.exe fourni avec ce logiciel. du Kit de ressources Windows Server 2003 / a>.

Exemple:

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


Vous pouvez également utiliser l’outil
Rechercher une clé privée fourni avec la fonction WCF. SDK, pour rechercher l’emplacement sur le disque du fichier de clé privée du certificat. Vous pouvez ensuite simplement utiliser ACL pour définir les droits appropriés sur le fichier.

Exemple:

FindPrivateKey My LocalMachine -n "CN=test"

C’est la solution que j’ai trouvée pour Windows Server 2008 si cela vous intéressait: http : //technet.microsoft.com/en-us/library/ee662329.aspx

En gros, je devais accorder des autorisations au service devant accéder au certificat à l'aide de l'outil MMC. Fonctionne comme un charme.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top