#HowTo Generar un archivo PFX con C# y Chilkat.

En este post te voy a explicar como puedes generar un archivo .Pfx a partir de la contraseña, el archivo .key y el archivo .cer con la librería Chilkat y C#.

Antes de empezar.

  • El ejemplo está codificado en Windows.
  • El ejemplo usa los certificados generados para facturación electrónica en México (SHA256/RSA 2048 bits).
  • Chilkat es un componente de paga, puedes requerir de  una clave de licencia válida.
  • Chilkat tiene un periodo de 30 días de prueba.
  • Chilkat requiere de Visual C++ Redistribuible.
  • Se requieren permisos de lectura y escritura en disco para la creación del archivo .Pfx.
  • Chilkat es multiplataforma y compatible con DotNet Core.
  • Puedes descargar el Package Nuget aquí, o los binarios en este vínculo.

Primeros pasos.

  1.  Obvio, debes descargar los componentes, ya sea descargándolos manualmente o con Nuget.
  2. Necesitas generar una ruta temporal de archivo, si solo necesitas los bytes del certificado. En el caso de que requieras guardar el archivo Pfx físico, necesitas saber con anticipación donde será guardado.
  3. Necesitas tener los bytes del archivo .key y .cer asignados en variables. También es necesaria la contraseña del certificado en texto plano.
  4. Creación de objetos PrivateKey y Cert. Estos dos objetos se componen a partir de los 3 insumos antes mencionados.

El código.

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Chilkat;
namespace HappyDevops.ChilkatPfxExample
{
class Program
{
static void Main()
{
//El archivo de pruebas es un certificado de pruebas, viejo y caduco.
var password = "12345678a";
var certFile = "MIIF0TCCA7mgAwIBAgIUMjAwMDEwMDAwMDAzMDAwMjI4MTYwDQYJKoZIhvcNAQELBQAwggFmMSAwHgYDVQQDDBdBLkMuIDIgZGUgcHJ1ZWJhcyg0MDk2KTEvMC0GA1UECgwmU2VydmljaW8gZGUgQWRtaW5pc3RyYWNpw7NuIFRyaWJ1dGFyaWExODA2BgNVBAsML0FkbWluaXN0cmFjacOzbiBkZSBTZWd1cmlkYWQgZGUgbGEgSW5mb3JtYWNpw7NuMSkwJwYJKoZIhvcNAQkBFhphc2lzbmV0QHBydWViYXMuc2F0LmdvYi5teDEmMCQGA1UECQwdQXYuIEhpZGFsZ28gNzcsIENvbC4gR3VlcnJlcm8xDjAMBgNVBBEMBTA2MzAwMQswCQYDVQQGEwJNWDEZMBcGA1UECAwQRGlzdHJpdG8gRmVkZXJhbDESMBAGA1UEBwwJQ295b2Fjw6FuMRUwEwYDVQQtEwxTQVQ5NzA3MDFOTjMxITAfBgkqhkiG9w0BCQIMElJlc3BvbnNhYmxlOiBBQ0RNQTAeFw0xNjEwMjUyMTU0MTlaFw0yMDEwMjUyMTU0MTlaMIG9MR4wHAYDVQQDExVNQiBJREVBUyBESUdJVEFMRVMgU0MxHjAcBgNVBCkTFU1CIElERUFTIERJR0lUQUxFUyBTQzEeMBwGA1UEChMVTUIgSURFQVMgRElHSVRBTEVTIFNDMSUwIwYDVQQtExxMQU44NTA3MjY4SUEgLyBGVUFCNzcwMTE3QlhBMR4wHAYDVQQFExUgLyBGVUFCNzcwMTE3TURGUk5OMDkxFDASBgNVBAsUC1BydWViYV9DRkRJMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjHr4KeoEx3BdkQP93AuN4fKo0rCZQsd9RJGBzQFvhmPJjGaVP81OUORM+lCRllxZxATZCAIFPOT3jl5wYgtolGYWWrt1HoAiuja1LKDGKrYgph0qWYKYeuew10fTyV+AeSbx1jTKz1PAAak06hx4M0rvmdiGO/Kg00/0wKz5/L3ZIMXEj+Hgr0IGh/yUIy8m5aKf+9jwuNttm/xDoeW3A8pxuidPU1Z1vliaZs75n89hC9LNwshhoaF3AvXIsgLDeuh9WoMGSm0HrilP9umFnm3nGUESiJa15Ep7LbG4CIhZrrknSm4fyrPk9KAigqLYMJhRsRwfp2qncAnAA+FuSQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAd7t48tgawC9aczrGYt+4GFRcjj1LVKV3NElG+VH2s51KPkKPLj2Sw6OiEOGd+49spxHj1VR5MFvJo/pEJLY3EuLTifC9YZZYC8pHNDiA/eSvKqW5JNzp5/rgs3qAG1GrfdNGuSD3FkqhDdB6tJYqzTc12IC7xEAhKXrWZYCqa+zb9ogtzrUVL3vRRLMpnGEHK2yx8dhvG35qjHEfXyuoBsWILrVmnPpDCFO/CCLQB1OuMti1mlir6voBN0L1EbFK30w2bEuVihAeVLX8vVfMq4ZPI7UTLnblGnN11CCqiZkWhhehYrMdCjb5thMkEA+CMlIaFJYp7pNkLxQd4Y5+r8pTrdxxyvpA51DIWdoxvwaOiz1bzZk6ElVY2rfxwyZaJ17cJ1jmS4Yb5P4h8+5zkmZnPmRqfmaVO3nsApLWP6A38ZBrwwss429PJMSpfeXKGysPsqwF0yP3blsM7Cw53393LSHGKNm2GgG0kcrHnbbku6z6fjBdXMQQ5vjPuMNyw/pe3PzQLVoNOrD5AOoZmSG2TI3DtY4edLdiGmNQjo3MmAMMq4s7lr4AELPWAZRbnOlD1nEWGLdRp1mViteDvXwBL9E98EB4K9xK21DvgJ6rzw/D9rX6epeANfoXazWC0iCYcBNXiPikApcW73a/Jl/WjkEwEdkL/jLj0KCep58=";
var keyFile = "MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIAgEAAoIBAQACAggAMBQGCCqGSIb3DQMHBAgwggS9AgEAMASCBMh4EHl7aNSCaMDA1VlRoXCZ5UUmqErAbucRBAKNQXH8t14jAYpBDzQIJ3ARNPvtVfGybZjOF6+rDa3lO0L1E7y+kmPfx4QJBXq1pLcoe2OxuCcNcJO8AyzdutAztFDzrOpuqoUy30JragQAGtwBFv1YdGSQT/1ODyLfpAZ7jsg0JpFpWZoBEThn/5UlO2ixxf0v1jzq+Pzv+Doz1H5GLHKUxwBDfdVAaJ3OGSRkBI+GtXp+V5sT5CNh3i4Jn+G1BKllMDIDBN0wVnOQv6ovxRREYMLhb9dcTVX3xceZjQJ9Q9NvU1OEaxxPcPbELC9oPjbjZgnjEvG/tXrbU4hxFwzePh9zOyEmeNt2LLIkCAvpZ2A90Aeu4IBPwEYMvWg4DbaNtZRw85TbLds8cX6GtpB1ETHD6gemPs9Q1mLsF4zRGZsFXPLkHr1+Pg8egb26Wv5+FcUm8Pah5lIMI+rk+C7L2lgoGIeh/CdEioI5a/VkbjiiA/Akfw65fg1hksZe19lBsuF1uh3zA+LKYwia3YvgYTajNKHWlDv/PVHO/Nw1WKCbiX2rFG35HU3PGUVcNh9/n8+UdOqI/9l0+M/uMbkzdbDX/D/+bmAtzHmJGixyrLft+ZzX+wRP2LATUHdzWKYMmHMkSjZVQaWCOI1o58YWR4j6r4ZqNEXwliQ/GlEIpvkldOmCjhc/167sKkMctxHLU2XkCRag04RrhZsN7iAneg4QnjrbPRHYtfaaf+L6a+L9I4UBsxHYU5lnL4uPBKj81pDQ+6ueyaMS4ItgPQYt7wbJU/QvVxgJ3S0sGTgYzO3EEoqmncdyEzQfnifqcqyTNpttoHhT5ncEIOUs8PZ5IUN57KRg6htyAsg1/vs4Hkl8g3sSCjC5tlYYxkANvUuZnvDcBIVaiY4SBi6kg5wb6Jq2gVf0NiHdgLjyjK/Ox+XjKJ/E12VE5cy0RNN75jcMnNskhA9vQLmwFDKmJWxggNcrdbhcCTvZGU5DODxRTD2Ks5Z+SwWsadULc2XilHGEpRB63zh/VnyUCIIdJuonyu6sGS6PRhYms/mC/bVL7O6gmWC5qmZpbKxf/5kcRs/uSjwlCOlahcfjPyUl3YwquI5IXd5eeLJx3h6MzO2Q8BCTb5czs5xamOL7/lG7yjiGysXi+CV6Dzf0MlO8vDk7FQsOiAKn8Kd76sQUFo9stSE1CqcJ+RCVMefZnZd71ZiBX56zxJm2qT9VJJDeW330MYqPIq7W8quttm9Fo9/LscJNJzYw1YdaQJdim787ONqt06/FIUpIKsgT/3i6w+byD5LW80UaqIh4calKETF8/X045C1xxfSsLsVmXO4AZ1/goJGlm1LXkKaenCteMoH6U3E+0nFjrxvd1C9H83JKoFFN5cqwt78Vz4sRfQqqQuxmjtnmbxM1yR/zd3mG7q1QX2rVITkiK4bse0ky8pdrYDTW9bGA7CBntGO5xutdwUEBfTo7kQZ4SwLJmyT9a/9w7ruTG2sQNDCHawWVP6BB75UnckEmA0g2xogCgK+n8LajU1qulDvt/ZgVkS6pv9TpI3o6I27sfSfIVXntBNvRUwry9Fw4SrW0f0jj6TCYUoUETo23Zv0H84Vf06Pkmy3vEwGhHO823iM=";
var bytesKey = Convert.FromBase64String(keyFile);
var bytesCer = Convert.FromBase64String(certFile);
var pfxPath = GetNewTempPathPfx();
var privateKey = ComposePrivateKeyComponent(bytesKey, password);
var cert = ComposeCertificateComponent(bytesCer, privateKey);
//Exportar en archivo certificado Pfx.
var success = cert.ExportToPfxFile(pfxPath, password, false);
Debug.Assert(success, "Error processing certificate..");
var bytesPfx = File.ReadAllBytes(pfxPath);
File.Delete(pfxPath);
//Procesar archivo PFX
ProcessCertificate(bytesPfx, password);
Console.Read();
}
private static void ProcessCertificate(byte[] bytesPfx, string password)
{
var certificate2 = new X509Certificate2(bytesPfx, password);
Console.WriteLine($"Serial Number: {certificate2.SerialNumber}");
Console.WriteLine($"SubjectName: {certificate2.SubjectName.Name}");
Console.WriteLine($"NotBefore: {certificate2.NotAfter.ToString(CultureInfo.InvariantCulture)}");
Console.WriteLine($"NotAfter: {certificate2.NotAfter.ToString(CultureInfo.InvariantCulture)}");
Debug.Assert(certificate2.HasPrivateKey, "Invalid pfx file...");
}
private static PrivateKey ComposePrivateKeyComponent(byte[] bytesKey, string password)
{
var privateKey = new PrivateKey();
privateKey.LoadPkcs8Encrypted(bytesKey, password);
return privateKey;
}
private static string GetNewTempPathPfx()
{
return $"{Path.GetTempPath()}/{Guid.NewGuid()}.tmp";
}
private static Cert ComposeCertificateComponent(byte[] bytesCert, PrivateKey privateKey)
{
var cert = new Cert();
cert.LoadFromBinary(bytesCert);
cert.SetPrivateKey(privateKey);
return cert;
}
}
}

Gustavo Sánchez

Soy especialista en escribir software de calidad. Mediante el uso de marcos de trabajo, técnicas y automatización de procesos he podido reducir los costes operativos de los sistemas de la empresa. Sistemas confiables y adaptables producen clientes felices.

Site Footer