Este es un resumen que hice en su día de los temas de criptografía para el examen de certificación. Lo pongo por aquí porque sigue siendo válido y por si a alguno le puede interesar.
Aquí encontraréis un resumen parecido elaborado por mi amigo Valeriano.
Criptografía Simétrica
Es el mecanismo de encriptación mediante el cual se pueden encriptar o desencriptar datos utilizando una clave secreta que debe ser conocida por el codificador y el decodificador del mensaje.
Criptografía Asimétrica
Es el mecanismo que permite encriptar o desencriptar datos mediante un par de claves, una privada, conocida solo por el codificador y otra pública, conocida por el decodificador.
La criptografía asimétrica, elimina el problema de la transmisión de la clave secreta entre el codificador y el decodificador del mensaje.
Usando la criptografía Simétrica con .net Framework
Las clases que proporcionan servicios de criptografía se encuentran agrupados en el espacio de nombres System.Security.Cryptography.
Se proporcionan 4 algoritmos para trabajar con criptografía simétrica:
Algoritmo
|
Longitud Máxima de la Clave
|
Descripción
|
RijndaelManaged
|
de 128 a 256 Bits, en incrementos de a 32 Bits
|
Es un estándar de encriptación del gobierno estadounidense. Cabe resaltar simplemente que a diferencia de los demás algoritmos, la clase está íntegramente implementada sobre código administrado.
|
DES
|
56 bits
|
Es un algoritmo de encriptación simétrico que utiliza claves relativamente cortas, con lo cual es vulnerable a ataques. Por esto, no debería ser utilizado.
|
RC2
|
Variable
|
Algoritmo surgido para solventar el problema de encriptación de claves cortas de DES.
|
TripleDES
|
156 bits, de los cuales son efectivos únicamente 112
|
Básicamente consiste en pasar el DES 3 veces.
|
Vector de Inicialización (IV): Es un valor utilizado por el algoritmo de encriptación simétrico para "oscurecer" el primer bloque de datos encriptados, lo que aumenta la dificultad de obtener un acceso no autorizado al mensaje.
Las clases utilizadas para trabajar con algoritmos simétricos derivan de System.Security.Cryptography.SymmetricAlgorithm, y exponen las siguientes propiedades y métodos:
Propiedades
|
|
BlockSize
|
Obtiene o establece el número de Bits (ojo, Bits no Bytes) que el algoritmo puede procesar en cada vuelta.
|
FeedBackSize
|
Obtiene o establece el FeedBackSize de la operación. Igual que la anterior, puede ser ignorada.
|
IV
|
Obtiene o establece el array de bytes utilizado como vector de inicialización del algoritmo.
|
Key
|
Obtiene o establece el array de bytes utilizado como clave por el algoritmo simétrico.
|
KeySize
|
Obtiene o establece el tamaño en bits de la clave utilizada.
|
|
Array de KeySizes que contiene los tamaños de clave admitidos por el algoritmo.
|
|
Array de KeySizes que contiene los tamaños de clave admitidos por el algoritmo.
|
|
Define uno de los aspectos del algoritmo de encriptación. Es uno de los valores definidos en la Enum CypherMode.
|
Métodos
|
|
CreateDecryptor
|
Crea el objeto ICryptoTransform que el objeto CryptoStream necesita para Desencriptar datos.
|
CreateEncryptor
|
Crea el objeto ICryptoTransform que el objeto CryptoStream necesita para Encriptar datos.
|
GenerateIV
|
Genera aleatoriamente un vector de inicialización para usar con el algoritmo.
|
GenerateKey
|
Genera aleatoriamente una clave para usar con el algoritmo.
|
ValidKeySize
|
Devuelve un bool que indica si el tamaño de la clase especificada en la propiedad Key es válido para ser utilizado con el algoritmo. Muy útil si trabajamos sin conocer exactamente qué algoritmo vamos a usar.
|
Creando una clave simétrica
Podemos crear una clave simétrica y un vector de inicialización a partir de una contraseña definida por el usuario mediante la clase Rfc2898DeriveBytes. Además de la contraseña del usuario, necesitaremos un valor de salto, que debe ser conocido por el codificador y el decodificador del mensaje.
Al constructor de la clase Rfc2898DeriveBytes pasaremos la clave definida por el usuario y el valor de salto, codificado en un array de bytes. Posteriormente obtendremos la clave y el vector de inicialización generados mediante el método GetBytes. A este método, debemos indicar en bytes, la longitud de la clave y el vector que necesitamos obtener.
Pasos para realizar operaciones de cifrado/descifrado
1- Crear el objeto SymmetricAlgorithm que contendrá la infraestructura relativa al algoritmo que vayamos a usar.
2- Especificar la clave simétrica y el IV o ambos.
3- Crear el objeto ICryptoTransform, llamando a SymmetricAlgorithm.CreateEncryptor() o SymmetricAlgorithm.CreateDecryptor() según la operación que vayamos a realizar.
4- Crear un objeto Stream, en que hará de origen o destino de los datos.
5- Crear un obeto CryptoStream unsando el Stream de datos que creamos en el paso 4 y el ICryptoTransform del paso 3.
6- Leer o Escribir en el CryptoStream como si fuera un Stream corriente.
Ejemplo:
Crearemos un WinForm en el que agregaremos los siguientes controles:
– Un ComboBox cmbAlgorithm que contendrá la lista de algoritmos disponibles.
– Un TextBox txtKey que contendrá la clave a utilizar para cifrar/descifrar.
– Un TextBox txtText que contendrá el texto sobre el que realizaremos la operación y en que mostraremos los resultados.
– Un Button btnEncrypt que lanzará el proceso de encriptación.
– Un Button btnDecrypt que lanzará el proceso de desencriptación.
Crearemos primeramente una función que nos devuelva el valor en el formato correcto para asignar a la Key o al IV.
Posteriormente, creamos esta función que nos permitirá encriptar o desencriptar según el parámetro
Finalmente, llamamos a la función en el Click de los botones
Criptografía Asimétrica
Algoritmos proporcionados por la plataforma: El algoritmo RSA y el DSA y las clases que lo implementan son RSACryptoServiceProvider y DSACryptoServiceProvider, respectivamente. Ambas implementaciones son una mera fachada del api de Windows que proporciona esta funcionalidad, y se ejecutan en código no administrado.
Al igual que los algoritmos simétricos, las clases que permiten implementar estos algoritmos derivan de System.Security.Cryptography.AsymmetricAlgorithm. Esta clase expone las siguientes propiedades:
Propiedades
|
|
KeyExchangeAlgorithm
|
Devuelve el nombre del algoritmo que se está utilizando.
|
KeySize
|
Devuelve el tamaño en bits de las claves utilizadas.
|
LegalKeySizes
|
Array con los tamaños de claves permitidos por el algoritmo.
|
SignatureAlgorithm
|
Devuelve la URL de un documento XML que describe la firma del algoritmo.
|
|
Devuelve o establece un bool que indica si la clave se almacenará en el CSP (Crypto Service Provider).
|
|
Obtiene o establece un valor que indica si la clave debe conservarse en el almacén de claves del equipo en lugar del almacén de perfiles de usuario.
|
Métodos expuestos por la clase RSACryptoServiceProvider
Decrypt
|
Desencripta datos encriptados con el algoritmo RSA
|
Encrypt
|
Encripta datos usando el algoritmo RSA
|
ExportParameters
|
Devuelve una estructura RSAParameters que representa los parámetros estándar (las claves privada/pública) para el algoritmo RSA. Admite un parámetro booleano que en caso de ser false incluye en la estructura únicamente la clave pública.
|
FromXmlString
|
Importa el par de claves a partir de la cadena xml suministrada.
|
ImportParameters
|
Carga el par de claves a partir de la estructura RSAParameters suministrada.
|
SignData
|
Calcula el valor hash de la matriz de bytes especificada mediante el algoritmo hash proporcionado y firma el valor hash resultante.
|
SignHash
|
Calcula la firma del valor hash especificado cifrándolo con la clave privada.
|
VerifyData
|
Verifica la firma especificada comparándola con el resultado de calcular la firma de los datos especificados.
|
VerifyHash
|
Verifica el valor hash especificado comparándola con el resultado de calcular el valor Hash para los datos especificados.
|
¿Cómo Importar y Exportar o persistir claves asimétricas?
Para exportar la claves de un algoritmo RSA, podemos recurrir al método ExportParameters de la clase RSACryptoServiceProvider, especificando en el único parámetro booleano admitido, si deseamos exportar tabién la clave privada. Este método nos devolverá una estructura RSAParameters que podemos convertir fácilmente a un array de bytes y transmitir o almacenar donde queramos.
Adicionalmente, la clase AsymmetricAlgorithm expone el método ToXmlString(), que podemos usar igualmente junto con FromXmlString() para realizar tareas de importación/exportación de claves.
También es posible abstraerse del medio de persistencia utilizando el almacenamiento proporcionado por el CSP (Crypto Service Provider). Para esto recurriremos al constructor de la clase RSACryptoServiceProvider que admite un parámetro de tipo CspParameters, pasándole una instancia de esta clase con la propiedad KeyContainerName establecida al nombre con el que identificaremos al par de claves en el almacenamiento.
Encryptar y Desencriptar mensajes usando el Algoritmo RSA
Para estas operaciones RSACryptoServiceProvider expone los métodos Encrypt() y Decrypt(); ambas devuelven un array de bytes con los datos transformados y requieren dos parámetros:
-byte[] rgb : Datos sobre los que se va a operar.
-bool fOAEP : Estableciéndolo a true, indicamos al método que utice el sistema OAEP para truncar los datos sobrantes. Lo importante de este parámetro es que debe usarse el mismo valor tanto para el cifrado como para la descifrado de los datos.
Algoritmos de Hash (does somebody knows the spanish translation of "hash"?)
Bueno, según el WordReference es "sofrito de carne".
En el argot informático, una clave hash es un valor que se calcula a partir de unos datos y que, al menos en teoría, identifica unívocamente a dichos datos. Estas claves tienen varias aplicaciones, ente ellas por ejemplo, la posibilidad de crear identificadores de archivos de gran tamaño, o la comprobación de la originalidad de un documento.
Al contrario que la operación de encriptación, la creación de una clave hash es un proceso irreversible; a partir del valor obtenido no se puede volver al dato original.
Existen dos tipos de algoritmos hash; los no cifrados y los cifrados. Los algoritmos hash cifrados o HMAC (Hash-based Message Authentication Code) se pueden utilizar para determinar si se ha manipulado un mensaje enviado a través de un canal no seguro, siempre que el remitente y el receptor compartan una clave secreta. El remitente calcula el valor hash para los datos originales y envía el valor hash y los datos originales como un solo mensaje. El receptor actualiza el valor hash en el mensaje recibido y comprueba que el código HMAC calculado coincide con el transmitido.
Cualquier cambio en los datos o en el valor hash producirá una desigualdad, ya que es necesario conocer la clave secreta para cambiar el mensaje y reproducir el valor hash correcto. Por consiguiente, si el original y los valores hash calculados coinciden, el mensaje se autentica.
Algoritmos no cifrados
Clase Abstracta
|
Clase Concreta
|
Descripción
|
MD5
|
MD5CryptoServiceProvider
|
Message Digest. El más usado. La longitud de la clave generada es de 128 bits.
|
RIPEMD160
|
RIPEMD160Managed
|
Su clave tiene 160 bits. Es nuevo en el framework 2.0 y se ha añadido con la intención de sustituir a MD5.
|
SHA1
|
SHA1CryptoServiceProvider
|
Secure Hash Algorithm. Su clave tiene 160 bits.
|
SHA256
|
SHA256Managed
|
Su clave tiene 256 bits.
|
SHA384
|
SHA384Managed
|
Su clave tiene 384 bits.
|
SHA512
|
SHA512Managed
|
Su clave tiene 512 bits.
|
Algoritmos cifrados
Clase
|
Descripción
|
HMACSHA1
|
Hash-based Message Authentication Code using SHA1. Admite claves HMAC de cualquier longitud y la clave generada tiene 160 bits.
|
MACTripleDES
|
Message Authentication Code using TripleDES. Admite claves de 8, 16 ó 24 bytes y genera claves de 64 bits.
|
Pasos para generar claves hash no cifradas
1- Crear el objeto Algoritmo
2- Trasladar los datos a tratar a un array de bytes o a un Stream
3- Llamar al método de cifrado HashAlgorithm.ComputeHash()
4- Obtener el array de bytes generado en la propiedad HashAlgorithm.Hash
Ejemplo: En una aplicación de consola, generamos el valor hash mediante el algoritmo MD5 para cualquier texto introducido por el usuario.
Pasos para generar claves hash cifradas
1- Crear la clave secreta que deberá ser compartida por las partes interesada
2- Crear el objeto algoritmo utilizando la clave secreta generada. Si no se especifica una clave, se creará una por defecto.
3- Trasladar los datos a tratar a un array de bytes o a un Stream.
4- Llamar al método de cifrado KeyedHashAlgorithm.ComputeHash()
5- Obtener el array de bytes generado en la propiedadKeyedHashAlgorithm.Hash
Ejemplo: En una aplicación de consola, generamos el valor hash mediante el algoritmo HMACSHA1
Y… cómo se yo si la hash es válida o no? (pendiente)
Firma de archivos
La firma digital de un archivo es un valor que puede adjuntarse a un fichero como prueba de que alguien, en posesión de una determinada clave privada ha creado un archivo y que éste no ha sido modificado desde su creación. No debe confundirse la firma digital con la encriptación. La firma digital no protege el secreto de un archivo; para ello, el archivo debe encriptarse.
Las clases que realizan la tarea de firma de archivos son DSACryptoServiceProvider y RSACryptoServiceProvider. Los métodos de estas clases encargados de estas operaciones son los siguientes:
SignHash
|
Genera una firma digital basada en la clave Hash de un archivo. |
SignData
|
Genera una firma digital generando primero la clave Hash de un archivo y luego generando la firma para dicha Hash. |
VerifyHash
|
Verifica que la firma especificada sea válida para la clave Hash especificada |
VerifyData
|
Verifica que la firma especificada sea válida para el contenido del archivo especificado. |
Pasos para generar la firma digital para un fichero
1- Crear el objeto algoritmo
2- Trasladar los datos a tratar a un array de bytes o a un stream
3- Llamar al método SignData() y guardar la firma
4- Exportar la clave publica
Pasos para comprobar la validez de una firma digital para un fichero
1- Crear el objeto algoritmo
2- Importar la firma digital y la clave pública
3- Trasladar los datos a verificar a un array de bytes o a un stream
4- Llamar al método VerifyData()
Ejemplo: En una aplicación de consola, generamos la firma digital para un archivo pasado por parámetro. El modificador -t como primer parámetro indica la acción de comprobar la validez de la firma.
Crossposted from crisfervil.com
Genial el resumen, a mi fue el tema que mas me gusto del 70-536 cuando le coges el truco es super interesante!!
Buen resumen. En sú día me saqué la certifiación 70-340, no sabía que existía una nueva, lo tendré que mirar.
Unas notas:
– No es lo mismo Cifrar (o Encriptar que en realidad es un anglicismo pero de tanto que se usa se convertirá (se ha convertido) en una palabra correcta en español) que codficar, en el resumen creo que puede generar dudas.
– Funcion Hash también se le conoce como función resumen. Pero vamos creo que lo mejor es usar el término Hash.
Saludos,
@jyeray: gracias!
@Fran: tomo nota de las sugerencia. Cifrar es más correcto que encriptar, que nisiquiera está admitido por la RAE. Pero me parece que se entiende perfectamente. He eliminado el término «codificar» allí donde he podido, sin tener que cambiar demasiado el texto.
Lo de Hash lo he mencionado porque me ha hecho gracia la traducción literal de la palabra.
@preguntoncojonero: todo llegará. De momento pasaré a limpio los resúmenes perdidos que tengo de cuando estuve preparándo estos exámenes.