Twitter Facebook Google + RSS Feed

Crear certificados de prueba para servidor y cliente

47
ASP.NETCertificados DigitalesIISSeguridad

Viernes, 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.

Certificados

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”.

Propiedades IIS

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.

Comunicaciones seguras

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


47 comentarios »

  1. pr dice:

    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

  2. Luciano dice:

    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

  3. Luciano dice:

    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!

  4. mkb dice:

    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?

  5. Felix dice:

    He tratado de hacer esto sobre WinServer 2008 R1 y no lo he logrado. ¿Es posible hacerlo?

  6. Maverifk dice:

    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

  7. Erika dice:

    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.

      • jose dice:

        No es posible que se haga a través de web? Podrías explicar porque? Yo tambien tengo que hacerlo.

        Un saludo y muchas gracias

        • José, no se puede firmar a través de la web por un tema sencillo: seguridad. Si pudieras leer la clave privada del certificado desde un, por ejemplo, un JavaScript, podrías enviarte esta clave a tu servidor y podrías firmar cualquier documento “en nombre” del usuario.
          Espero se entienda el concepto, sino avisame.
          Saludos.

          • jose dice:

            Hola Gustavo, muchas gracias por responderme.

            Tengo que hacer un desarrollo que firme documentos mediante web, actualmente he creado una web que mediante un control upload sube el pdf al servidor y con un certificado que obtenemos del usuario crea la firma en el pdf, igual como haceis en otro post que trata sobre esto.

            Como no se mucho sobre este tema no se si se genera el pdf correctamente, es decir yo veo que se ha generado y que tiene la marca de la firma pero no se si es correcta. Por ser a través de web no es válida? o no contiene la clave? Perdona por tanta pregunta pero estoy bastante verde en este tema.

            Un saludo y muchas gracias.

  8. Raul dice:

    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.

  9. Jose Pablo Cardenas dice:

    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.

  10. Ivana Curra dice:

    No funciona el código en C#. Hay un error de sintaxis. ¿Podrias decir cual es el correcto por favor? Gracias

  11. Carolina dice:

    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

  12. Omar dice:

    Hola Gustavo!!!!

    Muy buen articulo, me aclaro muchas dudas del como hacer certificados para pruebas, tengo la siguiente pregunta, de forma se puede generar un certificado que sirva aparte de autenticación para firmar documentos digitalmente ?… esto es posible?

    SAludos

  13. Omar dice:

    Gustavo, muchas gracias por la respuesta.

    Efectivamente estoy haciendo pruebas de certificado y tal como lo mencionas en un hambiente de operativo será necesario comprar los certificados. En cuanto al uso del comando MakeCert enn tu ejemplo generaste un certificado para autenticación, si quisiera hacer un certificado para firma digital debo especificar parametros diferentes supongo ?, hay algun tutorial de esta utileria MakeCert?

    Espero me puedas ayudar

    Te mando un saludo.

    • Hola, Omar.
      La verdad que no me acuerdo como había hecho el certificado de prueba cuando firmé un PDF, pero te paso algunos de los posibles valores para el parámetro -eku, o sea, el uso al que vamos a darle al certificado:

      Encrypting File System (1.3.6.1.4.1.311.10.3.4)
      Secure Email (1.3.6.1.5.5.7.3.4)
      Smart Card Logon (1.3.6.1.4.1.311.20.2.2)
      Client Authentication (1.3.6.1.5.5.7.3.2)
      Server Authentication (1.3.6.1.5.5.7.3.1)
      IP security IKE intermediate (1.3.6.1.5.5.8.2.2)

      Yo creo que si usás “1.3.6.1.5.5.7.3.2” (Client Authentication) podrás usar ese certificado para firmar un PDF.
      Por favor después contame si te sirvió.
      Suerte!

  14. jhosef dice:

    Hola Gustavo Felicidades, SOLO LO LEI PERO ME PARECE MUY INTERESANTE

    POR FAVOR QUISIERA QUE DME DIGFAS CUALES SON LOS PASOS PREVIOS PORFAVOR, YA QUE SOY UN USUARIO NOVATO.
    PARA PODERLO HACER DESDE CERO.
    SE TE AGRADECE MUCHO.

  15. hola gustavo. tengo una duda mortal. Segun estoy estudiando deberian de generarse una llave publica en el certificado y la llave privada deberia de estar a parte para uso solamente de quien genera el certificado. Asi la persona que recibi el certificado solamente tendra la lalve publica que la permitira encriptar con la llave publica hacia el la persona que emitio el certificado. Segun los ejemplos que pusiste las dos llaves a donde se generan ? revice y encuentro la llave publica en el certificado pero la llave privada ? en donde se genera ? y por otro lado porque al momento de desencriptar funciona ? de donde toma la llave privada ?
    te agradezco todo tu tiempo…

  16. Lepoldo dice:

    Saludos,

    Es posible usar un certificado para un web site emitido por una autoridad certificadora y al mismo tiempo utilizar certificados de cliente autofirmados creando un CA solo para este fin? O deben los certificados de clientes y del servidor ser generados por el mismo CA?

    Gracias!

  17. PEDRO LEIVA dice:

    Retomando el comentario de:Jose Pablo Cardenas del 6 de marzo del 2013, yo estoy en lo mismo, pero creo que más que configurar el IIS, también el código hay que ajustarlo, ya que tengo que accesar el store del lado del cliente. Como hago esto?

  18. Emanuel dice:

    Los artículos sobre Certificados Digitales me parecieron muy claros, me sacaron muchas dudas que tenía. Ahora alguien sabe de donde se pueden obtener estos certificados como para firmar Recibos de Sueldo Digitales para Argentina. Al parecer el único que los otorga es la empresa Encode SA lo cual me parece muy raro.

    Saludos y muchas gracias por estos tutoriales.

  19. RobertoCA dice:

    Estimado Gustavo :

    he comprado un certificado digital, como lo utilizo desde c# para fimar documentos XML, por favor podrias indicarme los pasos a seguir.
    Saludos y muchas gracias.

  20. Manel dice:

    Hola Gustavo,
    Muchas felicidades y muchas gracias por el post, me ha arrojado luz, pero tengo una duda:
    Tengo un certificado personal emitido por la Fábrica Nacional de Moneda y Timbre Española (FNMTE) que uso para distintas gestiones con el Ministerio Español.
    Por otro lado, estoy desarrollando una web en la que quiero autenticar a los usuarios mediante un certificado de cliente, como por ejemplo, el que tengo de FNMTE.
    En mi IIS he permitido a una carpeta para que acepte certificados de cliente. Cuando abro mi página web se me muestra la opción para escoger el certificado que quiera de los que tengo instalados, escojo el de FNMTE y entonces me muestra el siguiente error:
    Error HTTP 403.13 – Forbidden
    El certificado de cliente ha sido revocado o no ha podido determinarse el estado de revocación.

    ¿Cómo puedo solucionar esto desde el lado servidor?
    Espero que me puedas ayudar.

    Muchas gracias.

Deja un comentario

Buscar