Crear certificados de prueba para servidor y cliente
21Viernes, 26 de junio de 2009 a las 16:12hs por Gustavo Cantero (The Wolf)
Cuando estamos desarrollando una aplicación que utiliza certificados de cliente para autenticar a los usuarios debemos crear certificados de prueba para poder probar la aplicación, pero también se debe crear uno para utilizar con SSL en el Internet Information Server, y otro certificado que utilizaremos como entidad emisora de los certificados anteriores.
Para crear estos certificados de prueba utilizaremos la herramienta MakeCert, la cual crea archivos de certificado con sus pares de claves (pública y privada). Esta herramienta también asocia el par de claves al nombre especificado de una empresa y crea un certificado X.509 que enlaza el nombre especificado por un usuario con la parte pública del par de claves.
Cabe mencionar que esta aplicación, además de crear el archivo con el certificado, lo instala en uno de los repositorios de Windows, los cuales pueden verse, por ejemplo, desde el Internet Explorer, en el menú “herramientas”, “opciones de internet”, “contenido”, “certificados”, lo que abre una ventana como la que se muestra a continuación.

Esta es una de las herramientas que se incluyen en el Windows SDK, el cual viene con Visual Studio o puede bajarse de forma independiente de la siguiente dirección: http://msdn.microsoft.com/es-ar/windows/bb980924.aspx.
Como primer paso vamos a crear el certificado de la entidad emisora con los siguientes parámetros:
- Vamos a llamarlo “Scientia Root Auth” con la opción “-n” utilizando la nomenclatura definida en X.500
- Lo vamos a guardar en el repositorio personal (opción “-ss my”)
- Lo vamos a guardar a nivel de máquina (opción “-sr LocalMachine”)
- Vamos a utilizar el algoritmo SHA-1 para calcular el hash (opción “-a sha1”)
- Vamos a marcar la clave privada como exportable (opción “-pe”)
- Lo vamos a utilizar para firmar (opción “-sky signature”)
- Este certificado va a estar “autofirmado”, o sea, no va a ser creado por otra entidad emisora
Entonces, utilizando los parámetros descriptos en esta lista, el comando a ejecutar queda así:
makecert -pe -n "CN=Scientia Root Auth" -ss my -sr LocalMachine -a sha1 -sky signature -r "ScientiaRootAuth.cer"
Para confiar en este certificado, al ser autofirmado, tenemos que copiarlo al repositorio raíz de entidades de certificación de confianza (Trusted Root Certification Authorities), para lo cual vamos a utilizar otra herramienta que viene en el Windows SDK llamada “Certification Manager” (CertMgr). Esta herramienta puede utilizarse desde su interfaz gráfica o a través de la línea de comandos. Nosotros vamos a utilizarla a través de la línea de comandos para copiar el certificado:
certmgr -add -all -c "ScientiaRootAuth.cer" -s -r LocalMachine Root
Ahora vamos a crear el certificado para utilizar SSL en el Internet Information Server con el protocolo https:
- Vamos a marcar la clave privada como exportable (opción “-pe”)
- Vamos a utilizar la nomenclatura definida en X.500 para nombrarlo “localhost” (opción “-n”)
- Lo vamos a guardar en el repositorio personal (opción “-ss my”)
- Lo vamos a guardar a nivel de máquina (opción “-sr LocalMachine”)
- Vamos a utilizar el algoritmo SHA-1 para calcular el hash (opción “-a sha1”)
- Lo vamos a utilizar para intercambio de identidades (opción “-sky exchange”)
- Lo vamos a utilizar para autenticar el servidor (opción “-eku 1.3.6.1.5.5.7.3.1”)
- Vamos a utilizar como entidad emisora el certificado creado en el primer paso (opción “-in “Scientia Root Auth”)
- La cual está en el repositorio personal (opción “-is my”)
- A nivel de máquina (opción “-ir LocalMachine”)
- Establecemos el proveedor del CryptoAPI con la opción “-sp “Microsoft RSA SChannel Cryptographic Provider””
- Y el tipo de de proveedor CryptoAPI con la opción “-sy 12”
Entonces, utilizando los parámetros descriptos en esta lista, el comando a ejecutar queda así:
makecert -pe -n "CN=localhost" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "Scientia Root Auth" -is my -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 localhost.cer
Ahora podemos configurar el Internet Information Server para que utilice este certificado. En este ejemplo vamos a utilizar el IIS versión 5.1, aunque esta tarea puede realizarse con cualquier versión. Desde las propiedades del sitio web, en la solapa “Seguridad de directorios”, vamos a ver una sección llamada “Comunicaciones seguras”.

Ahí vamos a poder pulsar en el botón “Certificado de servidor…” y se nos va a abrir un “wizard” para crear, elegir o importar un certificado. En este ayudante vamos a seleccionar “asignar un certificado existente” y, en el paso siguiente, vamos a elegir el certificado llamado “localhost” (el creado en el paso anterior), luego ingresaremos el puerto que utilizaremos para SSL (por defecto es el 443), y listo, finalizamos el ayudante y ya podemos utilizar https en nuestro IIS.
Ahora, si necesitamos requerir que el usuario ingrese un certificado para autenticarse o para leer los datos del mismo, tenemos que crearlo. Para esto volveremos a utilizar la herramienta MakeCert, pero con algunos parámetros distintos:
- Vamos a marcar la clave privada como exportable (opción “-pe”)
- Vamos a utilizar la nomenclatura definida en X.500 para ingresar el nombre del usuario, el país, la empresa, la unidad organizativa y el mail (opción “-n”)
- Lo vamos a guardar en el repositorio personal (opción “-ss my”)
- Como es un certificado personal lo vamos a guardar a nivel de usuario (opción “-sr CurrentUser”)
- Vamos a utilizar el algoritmo SHA-1 para calcular el hash (opción “-a sha1”)
- Lo vamos a utilizar para intercambio de identidades (opción “-sky exchange”)
- Lo vamos a utilizar para autenticación del cliente (opción “-eku 1.3.6.1.5.5.7.3.2”)
- Vamos a utilizar como entidad emisora el certificado creado en el primer paso (opción “-in “Scientia Root Auth”)
- La cual está en el repositorio personal (opción “-is my”)
- A nivel de máquina (opción “-ir LocalMachine”)
- Establecemos el proveedor del CryptoAPI con la opción “-sp “Microsoft RSA SChannel Cryptographic Provider””
- El tipo de de proveedor CryptoAPI con la opción “-sy 12”
- Por último le vamos a establecerle 25000000 como número de serie (opción “-# 25000000”)
Ahora juntamos todos estos parámetros y el comando nos queda:
makecert -pe -n "CN=Gustavo Cantero, O=Scientia Soluciones Informaticas, OU=Desarrollo, E=g.cantero@Scientia.com.ar, C=AR" -ss my -sr CurrentUser -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.2 -in "Scientia Root Auth" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -# 25000000 GustavoCantero.cer
Bien, ahora para que el IIS le pida este certificado al usuario tenemos que habilitar SSL en la carpeta o sitio donde necesitamos el certificado, y establecerle que el usuario puede o debe seleccionar un certificado de cliente para autenticarse. Esto se hace desde la misma solapa “Seguridad de directorios” de las propiedades del sitio (o carpeta del sitio), pero pulsando sobre el botón “Modificar” de la sección “Comunicaciones seguras”, ahí vamos a pulsar sobre “Requerir canal seguro (SSL)” para que sólo pueda utilizarse a través de https, y “Requerir certificados de cliente”, para que el usuario deba seleccionar un certificado.

Dependiendo de la versión de IIS y del sistema operativo también vamos a poder vincular los certificados del cliente a usuarios del dominio y otras opciones más avanzadas, las cuales exceden el propósito de este artículo.
Ahora, al acceder al sitio vamos a ver que nos muestra que tenemos un certificado en el cual no confiamos, esto es porque el certificado raíz no está en el repositorio de confianza del Internet Explorer. Para seguir podemos pulsar sobre “Continuar con este sitio”, y luego de esto el navegador va a abrir una ventana para que elijamos un certificado de cliente, y en esa ventana vamos a ver el último certificado que creamos.
Como último paso vamos a leer el certificado y a mostrar la información básica desde una página de ASP.NET con el siguiente código agregado en el evento Load de la página:
HttpClientCertificate objCert = Request.ClientCertificate;
if (objCert.IsPresent)
{
if (objCert.IsValid)
{
System.Security.Cryptography.X509Certificates.X509Certificate2 objCert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(objCert.Certificate
Response.Write("Persona = " + objCert.Subject + "<br/>");
Response.Write("Emisor = " + objCert.Issuer + "<br/>");
Response.Write("Válido desde = " + objCert.ValidFrom + "<br/>");
Response.Write("Válido hasta = " + objCert.ValidUntil + "<br/>");
Response.Write("¿Es válido ? = " + objCert.IsValid + "<br/>");
Response.Write("Tamaño de la clave = " + objCert.SecretKeySize + "<br/>");
Response.Write("Nombre del certificado del servidor = " + objCert.ServerSubject + "<br/>");
Response.Write("Emisor del certificado del servidor = " + objCert.ServerIssuer + "<br/>");
Response.Write("Número de serie = " + objCert.SerialNumber + " - " + int.Parse(objCert2.SerialNumber, NumberStyles.HexNumber) + "<br/>");
Response.Write("Hash = " + objCert.CertEncoding + "<br/>");
}
else
Response.Write("El certificado no es válido");
}
else
Response.Write("No se ha encontrado un certificado");
Por último les dejo un archivo batch para crear los tres certificados en un paso.
En el próximo artículo mostraré algunos usos más avanzados de los certificados desde .NET.
Artículos relacionados
Categoria ASP.NET, Certificados Digitales, IIS, Seguridad | Etiquetas: Certificado Digital, X.509

Tengo este error talve sabe como resolverlo, el momento de enviar un mail con exchange
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated” string
No conozco mucho de Exchange Server, pero el error parecería ser porque no le está pasando el usuario y contraseña al servidor de SMTP.
Tal vez este artículo pueda ayudarte: http://smtp25.blogspot.com/2007/12/530-571-client-was-not-authenticated_25.html.
Suerte!
Hola Gustavo
Gracias por el articulo. Muy bueno!
Como verás, estoy haciendo honor al sitio… Programando a media noche!!
Consulta de un novato y sobre todo en lo que respecta a SSL y certificados.
Yo segui todo los pasos de este articulo. Creé el certificado de la entidad emisora, el del localhost y el mio personal. Por lo que veo, IIS y .NET reconocen mi certificado y me identifican. Mi pregunta es; en el caso de un sitio real:
cómo un usuario crea un certificado y se identifica con el mismo en un sitio publico?
Muchisimas gracias por todo!
Saludos
Gracias por tus comentarios, Luciano!
Sobre los certificados de cliente, seguro estos links te pueden ayudar:
Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication
IIS 7 Walkthrough: One to One Client Certificate Mapping Configuration
¡Suerte!
Gracias Gustavo
Estaba cometiendo un grave error.
Pense que el metodo Request.ClientCertificate devolvia el certificado con la clave privada. Evidentemente esto seria un grave problema de seguridad.
Muchas gracias por todo!
Todo me ha ido correcto, salvo al requerir un certificado de cliente para la autenticación. en Firefox me devuelve el siguiente mensaje de error:
An error occurred during a connection to localhost.
SSL received a record that exceeded the maximum permissible length.
(Error code: ssl_error_rx_record_too_long)
¿Cual puede ser el problema?
Es muy raro, más si sólo te da este error con Firefox.
¿Si navegás otro sitio como, por ejemplo, https://encrypted.google.com funciona bien o también te da este error?
Saludos.
He tratado de hacer esto sobre WinServer 2008 R1 y no lo he logrado. ¿Es posible hacerlo?
La verdad es que no lo probé en Win 2k8. ¿Qué error te da?
Interesante artículo, Gustavo. Muy bueno, me sirvió para crear unos certificados para probar un proceso de encriptado de pdf’s
En concreto, he usado la sintaxis que usas en el tercer ejemplo para crear dicho certificado ¿es correcto? ¿puede usarse para dichos fines?
Gracias
Si, si, se puede usar para eso.
Saludos.
Hola. Este sito me ayudo mucho.
Pero tengo que realizar los siguiente.
Localmente me funciona. estoy con vb.net.
pero ahora necesito que el usuario desde una aplicacion web me firme el documento pdf.
No he logrado realziar esto.
Mepodrian ayudar por favor.
Gracias.
Esto no es posible debido a que donde estás firmando los documentos es en el servidor, y los certificados del cliente no los tenés disponibles ahí.
Saludos.
Hola Gustavo.
Me ha servido mucho tu tutorial, he seguido paso a paso las indicaciones, pero me ha surgido un problema que no se como resolver, cuando abro una ventana del IE, en el URL pongo Https:\\localhost, me aparece una ventana solicitando el certificado, selecciono de la lista el certificado “Gustavo Cantero – Scientia Root Auth” despues de 3 intentos me envia una pagina que dice “No tiene autorización para ver esta página”, sabes como corregir el problema, ya intente detener el servidor y levantarlo de nuev para que reconozcalos cambios e asignacion de certificados pero no logro accesar exitosamente.
Me imagino que puede ser porque la entidad certificadora de tu certificado (que enredo) no está en un grupo de certificados de confianza del lado del servidor.
¿Probaste de crear todo con el .bat que está para descargarse en este artículo?
Buenas tardes.
Necesito con urgencia de su ayuda.
Tengo de implementar la autenticacion de usuarios en un sitio web. En mi pais existe una entidad que emite estos certificados, y se les entrega a los usuarios en una tarjeta junto a un lector.
El asunto es que cada certificado esta protegido por una clave.
Lo que necesitodesde mi sitio se lea basicamente es, que al momento que un usuario entre a un link en especifico de ni sitio se muestre una ventana con el certificado que se encuentra en la tarjeta (No se puede copiar, ni instalar en el equipo del usario), y al seleccionarlo le pida el PIN (O Clave), para que sea validado y que se otorgue la autorizacion de ingreso al sitio.
De verdad me urge montones de su ayuda, de antemano le agradezco el tiempo.
Yo creo que esto deberías charlarlo con el administrador de tu servidor, porque creo que tendrias que configurar el IIS para que le pida el certificado a la máquina del cliente.
O sea, es un tema de configuración del IIS, no de desarrollo.
Saludos.
No funciona el código en C#. Hay un error de sintaxis. ¿Podrias decir cual es el correcto por favor? Gracias
¿En qué línea te devuelve error de sintaxis?
Hola!!!
Soy nueva en estos temas de crear los certificados y hasta ahora estoy leyendo todos los comentarios,
pero la duda que me genera es en donde ejecuto este comando:
makecert -pe -n “CN=Scientia Root Auth” -ss my -sr LocalMachine -a sha1 -sky signature -r “ScientiaRootAuth.cer”
gracias por su atención
Hola, Carolina.
El makecert es una herramienta de línea de comandos, o sea, deberías ejecutarlo desde la línea de comandos.
Saludos.