Come impostare le autorizzazioni di lettura sul file della chiave privata del certificato X.509 da .NET

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

  •  06-07-2019
  •  | 
  •  

Domanda

Ecco il codice per aggiungere un pfx all'archivio 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();

Tuttavia, non sono riuscito a trovare un modo per impostare l'autorizzazione per NetworkService per accedere alla chiave privata.

Qualcuno può far luce? Grazie in anticipo.

È stato utile?

Soluzione

Per farlo a livello di codice, devi fare tre cose:

  1. Ottieni il percorso della cartella della chiave privata.

  2. Ottieni il nome del file della chiave privata all'interno di quella cartella.

  3. Aggiungi l'autorizzazione a quel file.

Vedi questo post per alcuni esempi di codice che fa tutti e tre (in particolare il metodo " AddAccessToCertificate ").

Altri suggerimenti

Questa risposta è in ritardo, ma volevo pubblicarla per chiunque venga qui a cercare:

Ho trovato un articolo del blog MSDN che ha fornito una soluzione utilizzando CryptoKeySecurity qui , ed ecco un esempio di soluzione in 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
    }
}

Sto usando un SecurityIdentifier per identificare l'account ma un NTAccount funzionerebbe altrettanto bene.

Nel caso in cui ciò aiuti qualcun altro, ho scritto la risposta di Jim Flood in 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 {

Nel caso in cui ciò aiuti qualcun altro, ho scritto la risposta di Jim Flood in Powershell

<*>

Nota che il parametro account può essere nella forma di " DOMINIO \ UTENTE " anche (non solo nomi predefiniti): l'ho provato nel mio ambiente e lo ha convertito automaticamente nel SID appropriato

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

Nota che il parametro account può essere nella forma di " DOMINIO \ UTENTE " anche (non solo nomi predefiniti): l'ho provato nel mio ambiente e lo ha convertito automaticamente nel SID appropriato

Puoi utilizzare lo lo strumento WinHttpCertCfg.exe fornito come parte degli Strumenti del Resource Kit di Windows Server 2003 .

Esempio:

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


In alternativa, è possibile utilizzare lo Trova lo strumento chiave privata fornito con WCF SDK, per trovare la posizione sul disco del file della chiave privata del certificato. Quindi puoi semplicemente usare ACL per impostare i giusti privilegi sul file.

Esempio:

FindPrivateKey My LocalMachine -n "CN=test"

Questa è la soluzione che ho trovato per Windows Server 2008 se qualcuno fosse interessato: http : //technet.microsoft.com/en-us/library/ee662329.aspx

Fondamentalmente, ho dovuto concedere le autorizzazioni al servizio che deve accedere al certificato utilizzando lo strumento MMC. Funziona come un fascino.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top