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.
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.
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.
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.
Hola José.
Fijate en este link de Adobe que te explica como validar la firma: Validate a digital signature.
Suerte!
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.
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
Si se puede crear un certificado para firmar documentos, fijate en este otro artículo que explico como crear un PDF firmado:
Cómo firmar un documento PDF desde C# con iTextSharp.
El problema de crear certificados de prueba para firmar es que cualquier otro usuario que abra el documento no va a poder verificar la autenticidad del mismo por no tener tu certificado ni la de la entidad certificante, por eso estos certificados se compran, por ejemplo, a VeriSign.
Suerte!
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!
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.
Hola.
No entiendo a qué te refieres con «los pasos previos», el artículo explica como crear los certíficados desde cero.
Si tienes una duda puntual escríbela que trataremos de ayudarte.
Suerte!
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…
Hola, Diego.
Al crear el certificado éste tiene ambas claves, por eso podés encriptar y desencriptar con el mismo certificado. Para pasárselo a otra persona deberías exportarlo pero sin la clave privada.
En la página Importar o exportar certificados y claves privadas te muestra como hacerlo, y fijate que cuando lo exportás hay un checkbox que dice «Exportar la clave privada», si no lo tildás la exportación sólo agregará la clave pública.
Suerte!
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!
Hola, Leopoldo.
Podés usar los certificados de esta manera, no habría problema, porque son para dos tareas distintas: el primero para encriptar la comunicación y el segundo para autenticar al usuario.
Suerte!
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?
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.
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.
Buenos días Roberto.
En este artículo explico como Utilizar certificados digitales desde .NET, y por si te interesa también podés ver este otro: Conceptos de Certificado Digital y Firma Digital.
Por último, también puede ser que te interese este artículo del MSDN que creo que explica lo que necesitás: How to: Sign XML Documents with Digital Signatures.
Suerte!
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.
Hola Manel.
Desconozco el tema de los certificados de la FNMTE, pero si el servidor lo revocó seguramente sea porque la entidad emisora de ese certificado no está como «de confianza» en el servidor. ¿Puede ser esto?
Saludos.
Hola Gustavo,
¿Cómo puedo actualizar la lista de entidades de confianza en mi servidor IIS7?
Muchas gracias
Seguramente te sirva este instructivo: Cómo configurar los certificados intermedios en un equipo que ejecuta IIS para la autenticación de servidor.
Suerte!
Muchas gracias, ahora lo investigo.
Por otra parte, me pide el certificado en el Page_Load, y yo querría que me lo pidiera en el momento de pulsar un botón y realizar la llamada Ajax al servidor.
¿Es esto posible?
No entiendo a qué te referís con «me pide el certificado en el Page_Load».
Saludos.
Hola Gustavo,
Me muestra la ventana para poder escoger el certificado personal que quiero de entre los que tengo instalados en el navegador en el momento que cargo la página, yo querría que lo hiciera cuando pulso un botón de la propia página. ¿Es esto posible?
Muchas gracias
Para eso creo que deberías poner la primer página sin seguridad, o sea, deberías configurar el IIS para que puedan entrar a ahí como anónimo, y desde un botón de esa página hacer un post a una segunda que esté con seguridad, entonces te va a pedir el certificado.
Suerte!
Hola. ¿Alguien sabe de algún curso gratuito o no (si es gratuito mejor) para aprender paso a paso como crear un sistema de autentificación con certificados digitales ?