c# - consumir - iis ssl certificate
Cómo establecer el permiso de lectura en el archivo de clave privada del certificado X.509 de.NET (5)
En caso de que esto ayude a alguien más, escribí la respuesta de Jim Flood en 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()
}
Tenga en cuenta que el parámetro de cuenta también puede tener la forma de "DOMINIO / USUARIO" (no solo nombres incorporados) - Probé esto en mi entorno y lo convirtió automáticamente al SID apropiado
Aquí está el código para agregar un pfx a la tienda de 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();
Sin embargo, no pude encontrar una forma de establecer el permiso para que NetworkService acceda a la clave privada.
¿Alguien puede arrojar algo de luz? Gracias por adelantado.
Esta es la solución que encontré para Windows Server 2008 si alguien estaba interesado: http://technet.microsoft.com/en-us/library/ee662329.aspx
Básicamente, tuve que otorgar permisos al servicio que necesita acceder al certificado usando la herramienta MMC. Funciona de maravilla.
Esta respuesta es tardía, pero quería publicarla para cualquier otra persona que venga a buscar aquí:
Encontré un artículo de blog de MSDN que dio una solución usando CryptoKeySecurity here , y aquí hay un ejemplo de una solución 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
}
}
Estoy usando un SecurityIdentifier para identificar la cuenta, pero una cuenta NTA funcionaría igual de bien.
Para hacerlo programáticamente, debes hacer tres cosas:
Obtenga la ruta de la carpeta de clave privada.
Obtenga el nombre de archivo de la clave privada dentro de esa carpeta.
Agrega el permiso a ese archivo.
Consulte esta publicación para obtener un código de ejemplo que hace los tres (específicamente, mire el método "AddAccessToCertificate").
Puede usar la herramienta WinHttpCertCfg.exe que se envía como parte de las herramientas del Kit de recursos de Windows Server 2003 .
Ejemplo:
winhttpcertcfg -g -c LOCAL_MACHINE/My -s test -a NetworkService
De forma alternativa, puede usar la herramienta Buscar clave privada que se envía con WCF SDK para encontrar la ubicación en el disco del archivo de clave privada del certificado. Luego puede simplemente usar ACL para establecer los privilegios correctos en el archivo.
Ejemplo:
FindPrivateKey My LocalMachine -n "CN=test"