| Artículos | 01 FEB 2004

Criptografía con .NET (y II)

Tags: Histórico
Cómo utilizar las herramientas criptográficas de .NET
Gonzalo Álvarez.
Hasta la llegada de .NET, programar aplicaciones que incorporasen sencillas operaciones criptográficas, como cifrar o calcular hashes, se convertía en una tarea complicada y propensa a errores. Gracias a .NET ya no es necesario recurrir al uso de la críptica CryptoAPI o al costoso diseño desde cero. Las nuevas clases de .NET facilitan sobremanera la programación de criptografía.

Microsoft ha facilitado enormemente la labor de los programadores poniendo la criptografía al alcance de todos gracias a las nuevas clases de seguridad de .NET. En este artículo se pretende acercar a todo tipo de programadores los conceptos fundamentales de la criptografía, a través de las clases implantadas por .NET.
En la primera parte de este artículo se repasaron algunos conceptos básicos de criptografía, como son el cifrado simétrico (o de clave secreta), los hashes y la generación de números aleatorios. En esta segunda parte se explica cómo utilizar los algoritmos de derivación de claves a partir de contraseñas, el cifrado asimétrico (o de clave pública) y las firmas digitales. Después de examinar de forma teórica cada tema, se introducen las clases de .NET relacionadas con operaciones criptográficas, contenidas en el espacio de nombres System.Security.Cryptography.

Claves a partir de contraseñas
Todos los algoritmos de cifrado, ya sean simétricos o asimétricos, requieren la utilización de claves. La seguridad de un algoritmo reside en la clave. Un criptosistema que haga uso de claves criptográficamente débiles será débil. Claves buenas son las cadenas de bits aleatorias generadas por medio de algún proceso automático (como una fuente aleatoria fiable o un generador pseudo-aleatorio criptográficamente seguro), de forma que si la clave consta de 64 bits, las 264 claves posibles sean igualmente probables. En el caso de los criptosistemas de clave pública, el proceso se complica, ya que a menudo las claves deben verificar ciertas propiedades matemáticas (ser primos dos veces, residuos cuadráticos, etc.).
Cuando se crea una nueva instancia de una clase criptográfica, como por ejemplo, TripleDESCryptoServiceProvider, siempre se genera automáticamente una nueva clave y un vector de inicialización (IV), que se colocan en las propiedades Key e IV respectivamente. En ocasiones tendrá que generar nuevamente claves para el mismo algoritmo. En este caso, puede crear una nueva instancia de una clase que implemente un algoritmo simétrico y después crear una nueva clave y un IV mediante una llamada a los métodos GenerateKey() y GenerateIV().
En el caso de los algoritmos asimétricos, cada vez que se crea una nueva instancia de una clase de algoritmo asimétrico se genera automáticamente un par de claves pública y privada con las características apropiadas.
En ocasiones se requiere que el usuario introduzca la clave del algoritmo. Pero claro, a un ser humano le resulta difícil recordar una cadena aleatoria de 128 bits de longitud. La solución al problema de la generación de claves seguras (y fáciles de recordar) por parte del usuario consiste en utilizar una frase o palabra suficientemente larga que posteriormente es convertida en una clave aleatoria por medio de un algoritmo (proceso denominado key-crunching).
La clase abstracta DeriveBytes representa cualquier algoritmo que deriva bytes adecuados para su uso como clave a partir de una entrada determinada. Concretamente, la clase PasswordDeriveBytes implanta uno de tales algoritmos, el PBKDF1 definido en el estándar PKCS #5 v2.0. Este algoritmo acepta como entrada cuatro parámetros: una contraseña o frase, un valor de salt (un valor aleatorio), el número de iteraciones y un algoritmo de hash. El algoritmo de derivación de la clave funciona aplicando repetidamente el algoritmo de hash a una combinación de la contraseña y el salt hasta devolver una secuencia de bytes de la longitud adecuada. Es muy conveniente utilizar un valor de salt generado aleatoriamente, aunque no necesitan guardarse en secreto (consulte el primer artículo para obtener más información sobre la generación de números aleatorios).
El siguiente código muestra cómo se puede derivar una clave de 128 bits (16 bytes) a partir de una cadena con la contraseña y de un salt:
Dim password As String = “HarryPotterYLaOrdenDelFenix”
Dim salt As Byte() = {23,12,132,99,2,123,221,190}
Dim pdb As New PasswordDeriveBytes( password, salt)
Dim derivedBytes As Byte() = pdb.GetBytes( 16 )

Algoritmos de cifrado asimétrico
Los orígenes de la criptografía de clave pública o asimétrica se remontan al artículo seminal de Diffie y Hellman en 1976, donde se explica la idea revolucionaria de servirse para las operaciones criptográficas de una pareja de claves, una pública, conocida por todos, y otra privada, sólo conocida por el usuario a quien le es asignada. Un mensaje puede ser cifrado por cualquier persona usando la clave pública, ya que es públicamente conocida, aunque sólo el poseedor de la clave privada podrá descifrarlo. Recíprocamente, un mensaje cifrado con la clave privada sólo puede ser cifrado por su poseedor, mientras que puede ser descifrado por cualquiera que conozca la clave pública.
En general, el cifrado asimétrico se emplea para cifrar las claves de sesión utilizadas para cifrar el documento, de modo que puedan ser transmitidas sin peligro a través de la Red junto con el documento cifrado, para que en recepción éste pueda ser descifrado. La clave de sesión se cifra con la clave pública del destinatario del mensaje, que aparecerá normalmente en una libreta de claves públicas o en un certificado digital. Por su parte, el cifrado asimétrico se emplea también para firmar documentos y autenticar entidades, como se describe más adelante.
Estos sistemas poseen la propiedad de que a partir del conocimiento de la clave pública no es posible determinar la clave privada. Los criptosistemas de clave pública, aunque más lentos que los simétricos, resultan adecuados para las funciones de autenticación, distribución de claves y firmas digitales.
Están basados en la desigual dificultad computacional (inviabilidad práctica) de ciertas operaciones: resultan muy sencillas en un sentido, pero sus inversas son muy complicadas cuando se trabaja con números suficientemente grandes. Algunos de los problemas intratables de que se sirven actualmente son la factorización (dificultad de descomponer un número compuesto suficientemente grande en sus factores) y los logaritmos discretos (dificultad de obtener el logaritmo de un número suficientemente grande).
En .NET los algoritmos de cifrado asimétrico o de clave pública se representan mediante la clase base abstracta AsymmetricAlgorithm y sus subclases. La plataforma .NET soporta dos algoritmos asimétricos: RSA, representado por la clase abstracta RSA, y DSA, representado por la clase abstracta DSA.
Para crear una instancia de un algoritmo se utiliza el método estático Create() de la clase del algoritmo. Por ejemplo, para crear un objeto RSA con claves aleatorias:
Dim RSA as rsa = RSA.Create()
La llamada al método Create() genera automáticamente una pareja de claves pública y privada. Si se desea especificar la pareja de claves pública y privada, deben importarse desde una estructura XML, similar a las utilizadas por el estándar de Firmas Digitales XML (XMLDSIG). Para importar

Contenidos recomendados...

Comentar
Para comentar, es necesario iniciar sesión
Se muestran 0 comentarios
X

Uso de cookies

Esta web utiliza cookies técnicas, de personalización y análisis, propias y de terceros, para facilitarle la navegación de forma anónima y analizar estadísticas del uso de la web. Consideramos que si continúa navegando, acepta su uso. Obtener más información