lunes, 22 de junio de 2009 a las 20:48hs por Gustavo Cantero (The Wolf)
Hace un par de semanas estuve dictando un curso sobre Certificados Digitales, Firma Digital y su utilización desde .NET, y me pareció interesante escribir algunos artículos sobre el tema para aquellos que necesitan hacer, por ejemplo, autenticación de usuarios a través de certificados de cliente, encriptación de la información a través de SSL, firma digital de documentos, etc.
Antes de comenzar a utilizar algunas herramientas y mostrarles código voy a hacer una breve introducción a algunos conceptos que son importantes que nos queden en claro.
Muy breve resumen de la historia de la criptografía
En la historia desde hace miles de años que el hombre trata de ocultar sus mensajes y escritos de ojos a los cuales no desea mostrar su contenido, y para esto encripta estos textos utilizando, en un principio, métodos sencillos que incluían el uso de lápiz, papel o alguna máquina sencilla. Luego, a principios del siglo XX, comenzó a utilizar máquinas mecánicas y electromecánicas, como la conocida máquina de rotores llamada Enigma, la cual fue utilizada por las fuerzas Alemanas desde 1930, proporcionando métodos de cifrado más complejos y eficientes.
La criptografía moderna comenzó cuando Claude Shannon publicó el artículo Communication Theory of Secrecy Systems en la Bell System Technical Journal en 1949, y poco tiempo después, junto a Warren Weaver, publicaron el libro Mathematical Theory of Communication. Estos documentos, juntos con otros publicados posteriormente, formaron las bases de la teoría de la criptografía, aunque fueron organizaciones gubernamentales secretas (como la NSA) las que siguieron con la investigación. Recién a mediados de los 70 hubieron grandes avances a nivel público: la creación del estándar de cifrado DES (Data Encryption Standard) y la creación de la criptografía asimétrica.
Métodos de cifrado
Los métodos de cifrado de la criptografía moderna se dividen, a gran escala, en dos: cifrado de flujo y cifrado de bloques, y éste último a su vez se divide en cifrado simétrico (con clave secreta) y cifrado asimétrico (con clave pública).
Cifrado de flujo
Los algoritmos de cifrado de flujo pueden realizar el cifrado incrementalmente, transformando el mensaje original en un mensaje cifrado bit a bit. Esto lo logra construyendo un generador de flujo de clave, el cual es una secuencia de bits de tamaño arbitrario que puede emplearse para oscurecer el contenido del flujo de datos combinando el flujo de clave con el flujo de datos mediante la función XOR. Si el flujo de clave es seguro, el flujo de datos cifrados también lo será.
Este método es utilizado en algunas aplicaciones como el cifrado de conversaciones telefónicas, donde el cifrado en bloques es inapropiado porque los flujos de datos se producen en tiempo real en pequeños fragmentos y las muestras de datos pueden ser muy pequeñas (hasta de 1 bit), y sería un desperdicio rellenar el resto de los bits antes de cifrar el mensaje y transmitirlo.
Cifrado por bloques
En este tipo de cifrado el mensaje se agrupa en bloques, por lo general de 128 bits o más, antes de aplicar el algoritmo de cifrado a cada parte de forma independiente utilizando la misma clave.
Cifrado simétrico
La criptografía simétrica es el método criptográfico que usa una misma clave para cifrar y descifrar los mensajes. Las dos partes que se comunican deben ponerse de acuerdo de antemano sobre la clave a utilizar y, una vez que ambas tienen acceso a esta clave, el remitente cifra el mensaje utilizándola, lo envía al destinatario, y éste lo descifra con la misma clave.
Existen algunos algoritmos muy conocidos, como el DES (Data Encryption Standard), el cual fue un diseño de unidad de cifrado por bloques de gran influencia desarrollado por IBM y publicado como estándar en 1977.
Cifrado asimétrico
El cifrado asimétrico es el método criptográfico que usa un par de claves para el envío de mensajes. Una de estas claves es pública y se puede entregar a cualquier persona, la otra clave es privada y el propietario debe guardarla de modo que nadie tenga acceso a ella. Los métodos criptográficos garantizan que ese par de claves sólo se puede generar una vez, de modo que se puede asumir que no es posible que dos personas hayan obtenido casualmente el mismo par de claves.
Si el remitente usa la clave pública del destinatario para cifrar el mensaje, una vez cifrado, sólo la clave privada del destinatario podrá descifrar este mensaje, ya que es el único que la posee. Por lo tanto se logra la confidencialidad del envío del mensaje, nadie salvo el destinatario puede descifrarlo, ni siquiera la misma persona que generó el mensaje.
Si el propietario del par de claves utiliza su clave privada para cifrar el mensaje, cualquiera que posea su clave pública podrá descifrarlo. En este caso se consigue tanto la identificación como la autenticación del remitente, ya que se sabe que sólo pudo haber sido él quien utilizó su clave privada (salvo alguien se la hubiese podido robar). Esta idea es el fundamento de la firma electrónica, de la cual hablamos más abajo.
Los sistemas de cifrado de clave pública o sistemas de cifrado asimétricos se crearon con el fin de evitar el problema del intercambio de claves que posee el sistema de cifrado simétrico. Con las claves públicas no es necesario que el remitente y el destinatario se pongan de acuerdo en la clave a emplear. Todo lo que se requiere es que, antes de iniciar la comunicación secreta, el remitente consiga una copia de la clave pública del destinatario. Es más, esa misma clave pública puede ser usada por cualquiera que desee comunicarse con su propietario.
Cabe mencionar que aunque una persona lograra obtener la clave pública, no podría descifrar el mensaje encriptado con esta misma clave, sólo podría encriptar mensajes que podrían ser leídos por el propietario de la clave privada.
Funciones de Hash
Las funciones de hash son métodos utilizados para generar valores que representen de manera unívoca a un conjunto de datos. Hash también se lo llama al resultado de dicha función o algoritmo.
Estas funciones se las utiliza para diversas aplicaciones, por ejemplo:
- Verificar la integridad de archivos
- Firmas digitales
- Tablas de Hash
Para ver más sobre «tablas de hash» los invito a ver el artículo Tablas de dispersión.
Estos métodos deben poseer algunas propiedades para poder utilizarse, las cuales detallo a continuación:
- Unidireccionales: a partir de un hash no debe poderse obtener el mensaje original.
- Compresión: a partir de cualquier mensaje, el hash obtenido siempre debe tener el mismo tamaño, por lo general, menor al mensaje.
- Difusión: el algoritmo debe utilizar todos los bits del mensaje, para que al cambiar un sólo bit se modifique el hash obtenido.
Existe una lista extensa de funciones públicas de hash que se pueden utilizar, y cada función tiene sus características. A continuación muestro una lista con las funciones de hash más conocidas, principalmente las dos primeras que además son las más utilizadas:
MD5 (Message-Digest Algorithm 5)
Algoritmo de 128 bits creado en 1991 por el profesor Roland Rivest del MIT como reemplazo del algoritmo MD4. Es uno de los algoritmos más utilizados aunque en 1996 se comprobó que se podía generar una colisión de hash, o sea, que a partir de un valor de hash de un documento se puede crear otro que, aunque no sea igual al original, genere el mismo valor de hash.
SHA-1 (Secure Hash Algorithm)
Creado en 1995 por la NSA, es similar al MD5, pero con un resultado de 160 bits. Existen otras variantes que modifican el diseño y longitud del resultado, conocidas como SHA-224, SHA-256, SHA-384 y SHA-512, llamándose SHA-2 a todos ellas.
HAS-160
Basado en SHA-1 y creado para utilizarse en el Korean Certificate-based Digital Signature Algorithm.
Gost
Definido originalmente en las Normas Unitarias del Gobierno Soviético GOST R 34.11-94. Genera un resultado de 256 bits.
Haval
Diseñado por Yuliang Zheng, Josef Pieprzyk, y Jennifer Seberry en 1992, permite generar hash en 14 longitudes distintas.
Panama
Creado en 1998 por Joan Daemen y Craig Clapp, genera resultados de 256 bits y puede utilizarse también como cifrado de flujo.
N-Hash
Creado por Nippon Telephone and Telegraph en 1990, genera un hash de 128 bits.
RIPEMD (RACE Integrity Primitives Evaluation Message Digest)
Creado en 1996, generando un resultado de 160 bits. Existen variantes de 128, 256 y 320 bits.
Snefru
Creado por Ralph Merkle en 1990, genera un hash de 128 o 256 bits. Se demostró que es inseguro.
Tiger
Creado por Ross Anderson y Eli Biham en 1995 para eficiencia en plataformas de 64 bits, genera un resultado de hasta 192 bits.
Certificados Digitales
Un Certificado Digital es un documento digital mediante el cual un tercero confiable (llamado autoridad de certificación o CA) garantiza la vinculación entre la identidad de un sujeto o entidad y su clave pública. Este documento contiene, entre otros datos, el nombre del usuario y su clave pública.
Los certificados digitales tienen distintos usos dependiendo de la finalidad para la cual se lo está utilizando, por ejemplo:
- Un certificado digital establece la identidad de un usuario en una red
- Los servidores pueden configurarse para permitir el acceso a usuarios con ciertos certificados o asignarle la identidad de un usuario del dominio según su certificado
- Los clientes pueden ser configurados para confiar en servidores que presentan ciertos certificados, por ejemplo, los que vienen preconfigurados en los navegadores para utilizarse en sesiones SSL.
- Los certificados pueden utilizarse para firma documentos electrónicos.
Una de las certificaciones más usadas y un estándar en la actualidad en infraestructuras de clave pública PKIs (Public-Key Infrastructure) es X.509 en su versión 3.
Certificado digital X.509
X.509 es un estándar publicado oficialmente en 1988 que especifica, entre otras cosas, formatos estándares para certificados de claves públicas y un algoritmo de validación de la ruta de certificación.
En X.509 se define una capa de abstracción para suministrar servicios de autenticación a los usuarios de un directorio X.500.
En la actualidad es ampliamente utilizado el formato de certificado digital X.509 v3, por ejemplo, para realizar conexiones seguras a servidores web a través de SSL (Secure Sockets Layer).
Este tipo de certificados posee un formato donde guarda distintos datos, por ejemplo, un número de serie, la clave pública del usuario, las fechas de validez del certificado, el nombre del usuario (en formato X.500), etc.
A continuación muestro un ejemplo de un certificado digital:
Número de Serie: | 21479 |
Versión X.509: | v3 |
Titular: | CN=Gustavo Cantero, E=gustavo@xxx.com.ar, OU=Persona no verificada – No amparado bajo el Decreto 427/98 de la IFDAPN, O=Política de Certificación de Correo Electrónico |
Emisor: | CN=AC de la Subsecretaría de la Gestión Pública para Certificados de Correo Electrónico, OU=Política de Certificación en http://ca.sgp.gov.ar, OU=No amparado por el Decreto 427/98 – IFD APN, OU=Subsecretaría de la Gestión Pública, O=Jefatura de Gabinete de Ministros, L=Ciudad de Buenos Aires, C=AR |
Validez (no antes de): | mié 03 jun 2009 – 19:14:35, ART |
(no después de): | jue 03 jun 2010 – 19:14:35, ART |
Algoritmo de firma: | sha1WithRSAEncryption |
Clave Pública: | E0EE 9902 0301 3081 8902 8181 00E5 AEA6 F074 5EDA 39A2 CF72 70C2 CC9C E7D6 014F 51BF 7A83 8851 4B07 B4BC 2D93 C422 AEC0 2026 9774 3C14 D54B 51E4 5F5C 434A 03F6 6F5C 4045 CC95 E27E 6C9C F5F6 2D99 6B6D 7CEC C786 ED61 D89B 47ED B46D 3B19 190D 86E8 C2FD 893E 01F2 850A B7AE 5806 9A60 9211 6AA2 374C B04E EE29 0340 C0CC 84F4 CE64 32F3 F035 D7E7 7B79 0001 |
Huella digital (MD5): | C68C 8538 6454 3D7C 222F 9176 B8D7 479C |
Huella digital (SHA1): | 4AFC 0115 CC50 0CFD B0D8 B564 68F5 F24E E47B BCFA |
Firma Digital
La firma digital hace referencia a un método criptográfico que asocia la identidad de una entidad (una persona o un equipo informático) a un mensaje o documento, pudiendo además, asegurar la integridad del documento o mensaje.
Para realizar esto se calcula el hash del documento, se encripta el resultado con la clave privada del certificado del usuario, y se adjunta al documento junto con el certificado (pero sin la clave privada, sólo con la pública).
Luego, para verificar la firma del documento, se lo abre, se valida el certificado adjunto (se verifica la fecha de validez, si la entidad emisora es de confianza, etc.), se obtiene la firma (el hash encriptado), se lo desencripta con la clave pública, se calcula el hash del documento (sin la firma) y se verifica que ambos hash, el desencriptado y el calculado, sean iguales.
En el próximo artículo escribiré como hacer paso a paso para generar certificados de prueba y configurar el Internet Information Server para utilizar SSL y certificados de cliente, y leer estos últimos desde ASP.NET.
Artículos relacionados
Categoria Certificados Digitales, Seguridad | Etiquetas: Certificado Digital, Firma Digital, X.509
Hola, gracias por la información y en espera del siguiente articulo, ojalá que pudieras poner algunos ejemplos de cifrado asimetrico con java. Excelente post, Felicidades
Buenas tardes, y dar tanto la enhorabuena como las gracias por toda la información compartida.
Lo tengo todo en asp.net, en vb, y funciona perfectamente en el ordenador donde lo desarrollo. Pero si lo alojo en un servidor web, accedo a la página alojada, y no es capaz de mostrarme los certificados de mi ordenador. Me imagino que es porque la web busca en el ordenador local, es decir, en el servidor. En vez de hacerlo en la máquina del cliente que consulta la web.
Podrías ayudarme??
Un saludo
Seguramente el problema sea por lo siguiente: el web server del Visual Studio corre en tu sesión, por lo cual, cualquier certificado que busques lo va a hacer con tu permisos, pero en el servidor no es así ya que usa el usuario del IIS. Prueba instalando el certificado en un repositorio a nivel de máquina (no de usuario) en el servidor.
Saludos.
Agradezco la respuesta Gustavo.
En mi caso no valdria. Lo tengo preparado para que el usuario utilice un lector de tarjetas por USB, y cuando éste inserta el DNI electronico o la tarjeta Izenpe (reconocida en el Pais Vasco), se puede leer el certificado de estas tarjetas.
De esa manera todos los usuarios de la web poseen en su mano su propio certificado para hacer las firmas de documentos. Si no entiendo mal, creando yo un repositorio deberia poner todos los certificados pertenecientes a los usuarios, y creo que algo asi no puede ser viable.
Un saludo
Perdón, que quizá este liandome mucho. Me doy cuenta que no se trata de reconocer el lector usb, sino simplemente los almacenes de certificados del ordenador cliente. Ya que si se inserta una tarjeta con certificado por usb automáticamente mete ese certificado al almacén del ordenador cliente.
Por lo tanto mi pregunta sigue siendo la primera que hice. Lograr que desde el servidor llegue a leer los certificados del ordenador cliente.
Saludos
José:
El problema en este caso es el siguiente: el usuario puede utilizar sus certificados para autenticarse en tu sitio pero no podés utilizar la clave privada de su certificado del lado del lado del servidor por un tema de seguridad.
Tal vez podrías crear algún componente que se ejecute del lado del cliente para firmar los documentos. Nosotros hicimos algo así en un cliente donde del lado del servidor creamos un PDF, utilizando una aplicación Silverlight enviamos los datos a firmar al cliente, el cliente elegía su certificado, firmábamos los datos, éstos se enviaban de nuevo al servidor y se terminaba de armar el PDF.
Espero que se entienda.
Suerte!
José, tienes en algún lugar algún ejemplo que me permita hacer eso que tu explicas, yo necesito que el usuario firme el documento en el cliente con su certificado y luego terminar el proceso en el serve “tipo realizar una firma básica con los datos del certificado del cliente y luego terminar con una firma avanzada en el server”… sabes de algún ejemplo o tienes algún articulo con código de ejemplo para usarlo como base…
Gracias,
Así es. En mi caso creo el pdf con pdfwriter, y quiero que seguidamente lo firme el usuario. Me veo casi obligado a no tener que mandar el documento para que lo firme desde alguna aplicación u otro método que no sea desde la web.
Se que tiene que existir alguna opción para poder hacerlo. De momento estoy haciendo pruebas con algo como esto:
Dim certCliente As HttpClientCertificate
certCliente = Request.ClientCertificate
If certCliente.IsPresent = True Then
If certCliente.IsValid = True Then
MsgBox(certCliente.Issuer)
MsgBox(certCliente.Issuer)
MsgBox(certCliente.ValidFrom)
MsgBox(certCliente.ValidUntil)
MsgBox(certCliente.Subject)
End If
End If
Pero me da como que no está presente el certificado.
Muchas gracias por la ayuda prestada, si lo consigo te informaré
Esto es lo que te comentaba: configurando el IIS podés hacer que le solicite el certificado al cliente, pero no vas a tener la clave privada de este certificado, sólo la pública, por lo tanto, no vas a poder firmar documentos del lado del server con su certificado.
Saludos.
Hace poco dimos de alta unos ficheros para la AGPD, y los firmamos digitalmente desde su web.
Es entonces que .net tiene sus limitaciones?
No, .NET no tiene limitaciones en este sentido. Seguramente esa entidad sea la que te dió el certificado, puede ser?
Si es asi es muy probable que ellos tengan guardado tu certificado con la clave privada, con el cual firman los documentos.
Saludos.
En nuestro caso, las tarjetas nos las facilitó Izenpe, y las hemos llegado a usar entre otras cosas, con la web de la agencia de protección de datos, que no tienen nada que ver con ellos.
A la hora de crear un fichero en su web donde registras el tipo de datos que das de alta, con formularios, etc. Finalmente dan la opción de mandarlo y firmarlo con varios métodos, y uno de ellos, firmando directamente, en nuestro caso con la tarjeta Izenpe.
Entonces, imagino yo, que deben utilizar algún componente instalado del lado del cliente, sino, cuando te logees en un sitio utilizando tu certificado el servidor podría «apropiarse» de tu certificado y suplantar tu identidad en otros sitios.
Volviendo a mirar esa web, muestro el link.
https://www.agpd.es/portalwebAGPD/canalresponsable/inscripcion_ficheros/Notificaciones_tele/obtencion_formulario/index-ides-idphp.php
Abajo del todo está la opción de formulario NOTA para titularidad privada.
Eliges que lo
Clickeas y te abre un pdf, Alta-tipo-eliges uno, y una vez lo completas, es desde ahí mismo donde eliges «internet firmado digitalmente», y a través del propio pdf realizas la firma digital y se envía.
Así que algo se podrá hacer preparando un pdf especial.
Lo acabo de ver y, como te comentaba en mi mensaje anterior, la firma del documento se realiza del lado del cliente utilizando el Adobe Reader, o sea, nunca se envía la clave privada del certificado del cliente al servidor.
Saludos.
Gracias Gustavo. Al menos ya se por dónde seguir buscando
De nada!
Ante cualquier otra consulta no dudes en escribir.
Suerte!
Buenos días de nuevo. Esta vez es sólo para informar.
No recuerdo donde, pero es posible descargarse la dll PDFViewer.dll, agregas el objeto que contiene a las herramientas, configuras para que sepa dónde coger el .pdf a mostrar, y de esa manera en la web queda incrustado el pdf sobre el que puede rellenar el usuario, y lo más importante, firmar.
Claro está que para eso se ha de preparar el pdf poniendo un recuadro dedicado a la firma que ponga el usuario. Y funciona.
Ahora sólo me queda hacer que nada más firmar, desde la web el usuario pueda enviar ese mismo pdf firmado.
Si necesitais más detalle comentarme y me explico mejor.
Saludos Gustavo
Buenos días de nuevo,
Es posible colocar la firma digital en un pdf escogiendo las coordenadas de su posición??
Siempre me lo pone en la parte inferior izquierda, y puedo decirle el tamaño de la firma pero no su posición en la página.
Gracias de antemano
Si, cuando defines el rectángulo que contendrá la firma las primeras dos coordenadas son la posición del mismo.
Suerte!
Certificados Digitales…
Un Certificado Digital es un documento digital mediante el cual un tercero confiable (llamado autoridad de certificación o CA) garantiza la vinculación entre la identidad de un sujeto o entidad y su clave pública. Este documento contiene, entre otros d…
Exelente el articulo, bien explicado y sin muchas vueltas, Saludos.
Amigo que tal, buen aporte el que tienes. Una consulta quería saber si es que tienes algún ejemplo para firmar un documento xml (factura electrónica de la SUNAT) con un certificado digital que compré a una empresa. Gracias de antemano por tu apoyo y tiempo
Hola Miguel.
Seguro te sirve esta página del MSDN donde tenés un ejemplo: Cómo: Firmar documentos XML con firmas digitales.
Suerte!
Amigo que tal disculpe me podrías brindar un número de contacto o correo para poder contactarme contigo. Gracias
Hola Miguel.
En nuestro sitio institucional (http://www.scientia.com.ar) tenés un botón de «contacto» para enviarnos mails.
Saludos!
Gustavo que tal.
Gracias por la respuesta, quería ver si me pudieras apoyar con un tema de facturación electrónica en Perú. quisiera saber como utilizar o crear XML a partir del Standar UBL 2.0. Si tienes algún ejemplo sobre ese tema.
Gracias por tu apoyo
Hola Miguel.
La verdad que nunca hice nada con el Standar UBL 2.0, pero si encontrás información por favor compartila con nosotros.
Suerte!