c# .net x509certificate pfx snk

c# - ¿Cómo crear un snk desde pfx/cer?



.net x509certificate (3)

Este es el mismo método proporcionado por en su answer , pero convertido a un script de PowerShell ( pfx2snk.ps1 ).

Param( [Parameter(Mandatory=$True,Position=1)] [string] $pfxFilePath, [string] $pfxPassword ) # The path to the snk file we''re creating [string] $snkFilePath = [IO.Path]::GetFileNameWithoutExtension($pfxFilePath) + ".snk"; # Read in the bytes of the pfx file [byte[]] $pfxBytes = Get-Content $pfxFilePath -Encoding Byte; # Get a cert object from the pfx bytes with the private key marked as exportable $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2( $pfxBytes, $pfxPassword, [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable); # Export a CSP blob from the cert (which is the same format as an SNK file) [byte[]] $snkBytes = ([Security.Cryptography.RSACryptoServiceProvider]$cert.PrivateKey).ExportCspBlob($true); # Write the CSP blob/SNK bytes to the snk file [IO.File]::WriteAllBytes($snkFilePath, $snkBytes);

Simplemente ejecute el script que proporciona la ruta y la contraseña del archivo pfx y creará un archivo snk en el mismo directorio que el archivo pfx (con el mismo nombre que no sea la extensión).

powershell.exe -File pfx2snk.ps1 -pfxFilePath cert.pfx -pfxPassword "pfx password"

O, si su pfx no tiene una contraseña (vergüenza, vergüenza):

powershell.exe -File pfx2snk.ps1 cert.pfx

Y, si tiene la mala suerte de estar trabajando en un entorno en el que no permiten que se ejecuten los scripts de PowerShell (es decir, solo sesiones interactivas de PowerShell), entonces puede ejecutar este feo liner desde una línea de comandos estándar de cmd.exe ( reemplazando las rutas de archivos y la contraseña pfx según sea necesario).

powershell.exe -Command "[IO.File]::WriteAllBytes(''SnkFilePath.snk'', ([Security.Cryptography.RSACryptoServiceProvider](New-Object System.Security.Cryptography.X509Certificates.X509Certificate2((Get-Content ''PfxFilePath.pfx'' -Encoding Byte), ''PfxPassword'', [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)).PrivateKey).ExportCspBlob($true));"

De hecho, uso esa línea única como parte estándar de mi proceso de creación previa de Visual Studio para automatizar el proceso de uso de las mismas claves de nuestros certificados de firma de autenticodo (archivo pfx) para una firma de nombre segura. Eso no es un requisito, pero me parece que tiene sentido que sean iguales y alimenta mis tendencias de TOC.

(Utilizo un archivo snk en lugar del pfx original porque he tenido la experiencia de "buggy" al usar archivos pfx para firmar con un nombre que mencionó en su respuesta)

Y, si está interesado, tengo algo como lo siguiente como parte de mi proceso posterior a la compilación en Visual Studio para agregar la firma autenticodo a la salida del proyecto (en las configuraciones del proyecto "Release" de todos modos).

powershell.exe -Command "Set-AuthenticodeSignature -FilePath ''$(TargetPath)'' -Certificate ''$(SolutionDir)MyCert.pfx'' -TimestampServer http://timestamp.verisign.com/scripts/timstamp.dll -HashAlgorithm sha256;"

Microsoft parece haber creado una jungla de certificación, que es difícil de entender.

  • Certificado de Microsoft X.509 (.cer)
  • Intercambio de información personal (.pfx)
  • Atributo de clave de firma de ensamblaje (.snk)

    1. ¿Sería recomendable crear un archivo snk basado en pfx o cer? (No estoy seguro de si es posible, y si es posible, ¿cómo se hace?)

    2. Si bien un ensamblaje puede firmarse con una contraseña protegida pfx, no parece tener un nombre seguro, a menos que esté firmado con snk. Pero el snk no tiene protección de contraseña. ¿Cuál es más seguro de usar? Como soy el único desarrollador en mi proyecto, no tengo el problema del entorno de seguridad de múltiples desarrolladores, pero aún me gustaría saber cuál es el mejor enfoque.

Muchas gracias,


Para generar un archivo snk desde un pfx:

sn -p keypair.pfx key.snk

Siempre he sido un fanático del uso de archivos snk sobre archivos .pfx, simplemente parecen menos buggy.


Una pequeña aclaración sobre los tipos de archivos mencionados:

  • Los archivos .cer son certificados X.509
  • Los archivos .pfx son certificados X.509 encriptados usando una clave simétrica basada en contraseña, también vea PKCS # 12 (Wikipedia)
  • Los archivos .snk solo contienen la clave RSA (pública / privada o pública solamente)

No importa si firma un ensamblaje utilizando .pfx -files o .snk -files , tendrá un nombre seguro en ambos sentidos. El almacenamiento de la clave RSA como un certificado cifrado ( .pfx ) es, por supuesto, más seguro que el almacenamiento de la clave no cifrada ( .snk ).

Puede extraer fácilmente la clave de esos archivos en el código usando la clase System.Security.Cryptography.X509Certificates.X509Certificate2 .

Para extraer la clave de .pfx :

/// <summary> /// Converts .pfx file to .snk file. /// </summary> /// <param name="pfxData">.pfx file data.</param> /// <param name="pfxPassword">.pfx file password.</param> /// <returns>.snk file data.</returns> public static byte[] Pfx2Snk(byte[] pfxData, string pfxPassword) { // load .pfx var cert = new X509Certificate2(pfxData, pfxPassword, X509KeyStorageFlags.Exportable); // create .snk var privateKey = (RSACryptoServiceProvider)cert.PrivateKey; return privateKey.ExportCspBlob(true); }

Use privateKey.ExportCspBlob(false) para extraer solo la clave pública! (por ejemplo, para la firma de demora de las asambleas)