Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se proporciona información general sobre los métodos y procedimientos de cifrado admitidos por .NET, incluidos los manifiestos ClickOnce.
Introducción a la criptografía
Las redes públicas, como Internet, no proporcionan un medio de comunicación segura entre entidades. La comunicación a través de dichas redes es susceptible de ser leída o incluso modificada por terceros no autorizados. La criptografía ayuda a proteger los datos de ser vistos, proporciona maneras de detectar si se han modificado los datos y ayuda a proporcionar un medio seguro de comunicación en otros canales no seguros. Por ejemplo, los datos se pueden cifrar mediante un algoritmo criptográfico, transmitidos en un estado cifrado y posteriormente descifrados por la entidad deseada. Si un tercero intercepta los datos cifrados, será difícil descifrarlos.
En .NET Framework, las clases del espacio de nombres System.Security.Cryptography se ocupan de administrar muchos de los detalles de criptografía. Algunos son contenedores para implementaciones de sistema operativo, mientras que otros son implementaciones puramente administradas. No es necesario ser un experto en criptografía para usar estas clases. Al crear una nueva instancia de una de las clases de algoritmo de cifrado, las claves se generan automáticamente para facilitar el uso y las propiedades predeterminadas son lo más seguras y seguras posible.
Primitivos criptográficos
En una situación típica en la que se usa la criptografía, dos partes (Alice y Bob) se comunican a través de un canal no seguro. Alice y Bob quieren asegurarse de que su comunicación sigue siendo incomprensible por cualquier persona que esté escuchando. Además, dado que Alice y Bob están en ubicaciones remotas, Alice debe asegurarse de que la información que recibe de Bob no ha sido modificada por nadie durante la transmisión. Además, debe asegurarse de que la información realmente se origina de Bob y no de alguien que suplanta a Bob.
La criptografía se usa para lograr los objetivos siguientes:
Confidencialidad: para ayudar a proteger la identidad de un usuario o evitar que se lean sus datos.
Integridad de los datos: para ayudar a proteger los datos de ser modificados.
Autenticación: para asegurarse de que los datos se originan en una entidad determinada.
Sin rechazo: para evitar que una determinada parte niegue que envió un mensaje.
Para lograr estos objetivos, puede usar una combinación de algoritmos y prácticas conocidos como primitivos criptográficos para crear un esquema criptográfico. En la tabla siguiente se enumeran los primitivos criptográficos y sus usos.
Primitivo criptográfico | Uso |
---|---|
Cifrado de clave secreta (criptografía simétrica) | Realiza una transformación en los datos para evitar que los terceros los lean. Este tipo de cifrado usa una clave secreta compartida única para cifrar y descifrar datos. |
Cifrado de clave pública (criptografía asimétrica) | Realiza una transformación en los datos para evitar que los terceros los lean. Este tipo de cifrado usa un par de claves pública y privada para cifrar y descifrar datos. |
Firma criptográfica | Ayuda a comprobar que los datos se originan en una entidad específica mediante la creación de una firma digital única para esa entidad. Este proceso también usa funciones hash. |
Hash criptográficos | Asigna datos de cualquier longitud a una secuencia de bytes de longitud fija. Los hashes son estadísticamente únicos; una secuencia diferente de dos bytes no generará el mismo hash. |
Cifrado de clave secreta
Los algoritmos de cifrado de clave secreta usan una sola clave secreta para cifrar y descifrar datos. Debe proteger la clave del acceso por agentes no autorizados, ya que cualquier entidad que tenga la clave puede usarla para descifrar los datos o cifrar sus propios datos, reclamando que se originó de usted.
El cifrado de clave secreta también se conoce como cifrado simétrico porque se usa la misma clave para el cifrado y el descifrado. Los algoritmos de cifrado de clave secreta son muy rápidos (en comparación con los algoritmos de clave pública) y son adecuados para realizar transformaciones criptográficas en grandes flujos de datos. Los algoritmos de cifrado asimétrico, como RSA, se limitan matemáticamente en la cantidad de datos que pueden cifrar. Por lo general, los algoritmos de cifrado simétricos no tienen esos problemas.
Un tipo de algoritmo de clave secreta denominado cifrado de bloques se usa para cifrar un bloque de datos a la vez. Los cifrados de bloques, como el estándar de cifrado de datos (DES), tripleDES y el estándar de cifrado avanzado (AES) transforman criptográficamente un bloque de entrada de n bytes en un bloque de salida de bytes cifrados. Si desea cifrar o descifrar una secuencia de bytes, debe hacerlo bloque por bloque. Dado que n es pequeño (8 bytes para DES y TripleDES; 16 bytes [el valor predeterminado], 24 bytes o 32 bytes para AES), los valores de datos que son mayores que n deben cifrarse un bloque cada vez. Los valores de datos que son más pequeños que n deben expandirse a n para poder procesarse.
Una forma simple de cifrado de bloques se denomina modo de código electrónico (ECB). El modo ECB no se considera seguro, ya que no usa un vector de inicialización para inicializar el primer bloque de texto no cifrado. Para una clave secreta determinada k, un cifrado de bloque simple que no usa un vector de inicialización cifrará el mismo bloque de entrada de texto no cifrado en el mismo bloque de salida de texto cifrado. Por lo tanto, si tiene bloques duplicados en la secuencia de texto no cifrado de entrada, tendrá bloques duplicados en la secuencia de texto cifrado de salida. Estos bloques de salida duplicados alertan a los usuarios no autorizados al cifrado débil que usaron los algoritmos que podrían haberse empleado y los posibles modos de ataque. Por lo tanto, el modo de cifrado ECB es bastante vulnerable al análisis y, en última instancia, la detección de claves.
Las clases de cifrado de bloques que se proporcionan en la biblioteca de clases base usan un modo de encadenamiento predeterminado denominado encadenamiento de bloques de cifrado (CBC), aunque puede cambiar este valor predeterminado si lo desea.
Los cifrados CBC superan los problemas asociados con los cifrados ECB mediante un vector de inicialización (IV) para cifrar el primer bloque de texto no cifrado. Cada bloque posterior de texto no cifrado se somete a una operación OR (XOR
) exclusiva bit a bit con el bloque de texto cifrado anterior antes de que se cifre. Por lo tanto, cada bloque de texto cifrado depende de todos los bloques anteriores. Cuando se usa este sistema, los encabezados de mensaje comunes que podrían ser conocidos por un usuario no autorizado no se pueden usar para realizar ingeniería inversa de una clave.
Una manera de poner en peligro los datos cifrados con un cifrado CBC es realizar una búsqueda exhaustiva de cada clave posible. Dependiendo del tamaño de la clave que se usa para realizar el cifrado, este tipo de búsqueda es muy lento usando incluso los equipos más rápidos y, por tanto, es inviable. Los tamaños de clave más grandes son más difíciles de descifrar. Aunque el cifrado no hace que teóricamente sea imposible que un adversario recupere los datos cifrados, aumenta el costo de hacerlo. Si se tarda tres meses en realizar una búsqueda exhaustiva para recuperar datos que son significativos solo durante unos días, el método de búsqueda exhaustivo no es práctico.
La desventaja del cifrado de clave secreta es que presupone que dos partes han acordado una clave e IV, y han comunicado sus valores. El vector de inicialización no se considera secreto y se transmite como texto simple con el mensaje. Sin embargo, la clave debe mantenerse secreta de usuarios no autorizados. Debido a estos problemas, el cifrado de clave secreta se usa a menudo junto con el cifrado de clave pública para comunicar de forma privada los valores de la clave y iv.
Suponiendo que Alice y Bob son dos partes que quieren comunicarse a través de un canal no seguro, podrían usar el cifrado de clave secreta de la siguiente manera: Alice y Bob aceptan usar un algoritmo determinado (AES, por ejemplo) con una clave determinada e IV. Alice redacta un mensaje y crea una secuencia de red (quizás una canalización con nombre o un correo electrónico de red) en la que enviar el mensaje. A continuación, cifra el texto con la clave y el IV, y envía el mensaje cifrado e IV a Bob a través de la intranet. Bob recibe el texto cifrado y lo descifra utilizando el IV y la clave previamente acordada. Si se intercepta la transmisión, el interceptor no puede recuperar el mensaje original, porque no conocen la clave. En este escenario, solo la clave debe permanecer secreta. En un escenario real, Alice o Bob genera una clave secreta y usa el cifrado de clave pública (asimétrica) para transferir la clave secreta (simétrica) a la otra parte. Para obtener más información sobre el cifrado de clave pública, consulte la sección siguiente.
.NET proporciona las siguientes clases que implementan algoritmos de cifrado de clave secreta:
HMACSHA256, HMACSHA384 y HMACSHA512. (Estos son algoritmos de clave secreta técnicamente porque representan códigos de autenticación de mensajes que se calculan mediante una función hash criptográfica combinada con una clave secreta. Consulte Valores hash, más adelante en este artículo).
Cifrado de clave pública
El cifrado de clave pública usa una clave privada que debe mantenerse secreta de usuarios no autorizados y una clave pública que se puede hacer pública a cualquier usuario. La clave pública y la clave privada están vinculadas matemáticamente; los datos cifrados con la clave pública solo se pueden descifrar con la clave privada y los datos firmados con la clave privada solo se pueden comprobar con la clave pública. La clave pública se puede poner a disposición de cualquier persona; se usa para cifrar los datos que se enviarán al guardián de la clave privada. Los algoritmos criptográficos de clave pública también se conocen como algoritmos asimétricos porque se requiere una clave para cifrar los datos y se requiere otra clave para descifrar los datos. Una regla criptográfica básica prohíbe la reutilización de claves y ambas claves deben ser únicas para cada sesión de comunicación. Sin embargo, en la práctica, las claves asimétricas suelen durar bastante tiempo.
Dos partes (Alice y Bob) pueden usar el cifrado de clave pública como se indica a continuación: En primer lugar, Alice genera un par de claves pública y privada. Si Bob quiere enviar a Alice un mensaje cifrado, le pide su clave pública. Alice envía a Bob su clave pública a través de una red no segura y Bob usa esta clave para cifrar un mensaje. Bob envía el mensaje cifrado a Alice y lo descifra mediante su clave privada. Si Bob recibió la clave de Alice a través de un canal no seguro, como una red pública, Bob es vulnerable a un ataque de intermediario. Por lo tanto, Bob debe comprobar con Alice que tiene una copia correcta de su clave pública.
Durante la transmisión de la clave pública de Alice, un agente no autorizado podría interceptar la clave. Además, el mismo agente podría interceptar el mensaje cifrado de Bob. Sin embargo, el agente no puede descifrar el mensaje con la clave pública. El mensaje solo se puede descifrar con la clave privada de Alice, que no se ha transmitido. Alice no usa su clave privada para cifrar un mensaje de respuesta a Bob, porque cualquier persona con la clave pública podría descifrar el mensaje. Si Alice quiere enviar un mensaje a Bob, le pide a Bob su clave pública y cifra su mensaje con esa clave pública. A continuación, Bob descifra el mensaje con su clave privada asociada.
En este escenario, Alice y Bob usan el cifrado de clave pública (asimétrica) para transferir una clave secreta (simétrica) y usar el cifrado de clave secreta durante el resto de su sesión.
En la lista siguiente se ofrecen comparaciones entre los algoritmos criptográficos de clave pública y clave secreta:
Los algoritmos criptográficos de clave pública usan un tamaño fijo de búfer, mientras que los algoritmos criptográficos de clave secreta usan un búfer de longitud variable.
Los algoritmos de clave pública no se pueden usar para encadenar datos en secuencias de la forma en que los algoritmos de clave secreta pueden, ya que solo se pueden cifrar pequeñas cantidades de datos. Por lo tanto, las operaciones asimétricas no usan el mismo modelo de streaming que las operaciones simétricas.
El cifrado de clave pública tiene un espacio de claves mucho mayor (intervalo de valores posibles para la clave) que el cifrado de clave secreta. Por lo tanto, el cifrado de clave pública es menos susceptible a ataques exhaustivos que prueban todas las claves posibles.
Las claves públicas son fáciles de distribuir porque no tienen que protegerse, siempre que exista alguna manera para comprobar la identidad del remitente.
Algunos algoritmos de clave pública (como RSA y DSA, pero no Diffie-Hellman) se pueden usar para crear firmas digitales para comprobar la identidad del remitente de los datos.
Los algoritmos de clave pública son muy lentos en comparación con los algoritmos de clave secreta y no están diseñados para cifrar grandes cantidades de datos. Los algoritmos de clave pública solo son útiles para transferir cantidades muy pequeñas de datos. Normalmente, el cifrado de clave pública se usa para cifrar una clave e IV para que lo use un algoritmo de clave secreta. Después de transferir la clave e IV, se usa el cifrado de clave secreta durante el resto de la sesión.
.NET proporciona las siguientes clases que implementan algoritmos de clave pública:
RSA permite el cifrado y la firma, pero DSA solo se puede usar para la firma. DSA no es tan seguro como RSA y se recomienda RSA. Diffie-Hellman solo se puede usar para la generación de claves. En general, los algoritmos de clave pública son más limitados en sus usos que los algoritmos de clave privada.
Firmas digitales
Los algoritmos de clave pública también se pueden usar para formar firmas digitales. Las firmas digitales autentican la identidad de un remitente (si confía en la clave pública del remitente) y ayudan a proteger la integridad de los datos. Con una clave pública generada por Alice, el destinatario de los datos de Alice puede comprobar que Alice lo envió comparando la firma digital con los datos de Alice y la clave pública de Alice.
Para usar la criptografía de clave pública para firmar digitalmente un mensaje, Alice aplica primero un algoritmo hash al mensaje para crear un resumen de mensaje. El resumen del mensaje es una representación compacta y única de los datos. A continuación, Alice cifra el resumen del mensaje con su clave privada para crear su firma personal. Al recibir el mensaje y la firma, Bob descifra la firma mediante la clave pública de Alice para recuperar el resumen del mensaje y aplica un hash al mensaje mediante el mismo algoritmo hash que Alice usó. Si el resumen del mensaje que Bob calcula coincide exactamente con el resumen del mensaje recibido de Alice, Bob está seguro de que el mensaje procede del posesor de la clave privada y que los datos no se han modificado. Si Bob confía en que Alice es el posesor de la clave privada, sabe que el mensaje procede de Alice.
Nota:
Cualquier persona puede comprobar una firma porque la clave pública del remitente es un conocimiento común y normalmente se incluye en el formato de firma digital. Este método no conserva el secreto del mensaje; para que el mensaje sea secreto, también debe cifrarse.
.NET proporciona las siguientes clases que implementan algoritmos de firma digital:
Valores hash
Los algoritmos hash asignan valores binarios de una longitud arbitraria a valores binarios más pequeños de una longitud fija, conocidos como valores hash. Un valor hash es una representación numérica de un fragmento de datos. Si aplica un hash a un párrafo de texto no cifrado y cambia incluso una letra del párrafo, un hash posterior generará un valor diferente. Si el hash es criptográficomente seguro, su valor cambiará significativamente. Por ejemplo, si se cambia un solo bit de un mensaje, una función hash segura puede generar una salida que difiere en un 50 %. Muchos valores de entrada pueden aplicar un hash al mismo valor de salida. Sin embargo, técnicamente es poco factible encontrar dos entradas distintas cuyo valor hash sea el mismo.
Dos partes (Alice y Bob) podrían usar una función hash para garantizar la integridad del mensaje. Seleccionarían un algoritmo hash para firmar sus mensajes. Alice escribiría un mensaje y, a continuación, crearía un hash de ese mensaje mediante el algoritmo seleccionado. A continuación, seguirían uno de los métodos siguientes:
Alice envía el mensaje de texto no cifrado y el mensaje hash (firma digital) a Bob. Roberto recibiría el mensaje y le aplicaría el algoritmo hash. A continuación, compararía su valor hash con el valor hash que recibió de Alicia. Si los valores hash son idénticos, el mensaje no se modificó. Si los valores no son idénticos, el mensaje se modificó después de que Alice lo escribió.
Desafortunadamente, este método no establece la autenticidad del remitente. Cualquier persona puede suplantar a Alice y enviar un mensaje a Bob. Pueden usar el mismo algoritmo hash para firmar su mensaje, y todo lo que Bob puede determinar es que el mensaje coincide con su firma. Esta es una forma de ataque de tipo "Man in the middle". Para obtener más información, vea Cryptography Next Generation (CNG) Secure Communication Example ( Ejemplo de comunicación segura de criptografía de próxima generación [CNG]).
Alice envía el mensaje de texto no cifrado a Bob a través de un canal público no seguro. Envía el mensaje hash a Bob a través de un canal privado seguro. Bob recibe el mensaje de texto no cifrado, calcula su hash y compara el hash con el hash que se intercambió de forma privada. Si los hashes coinciden, Bob sabe dos cosas:
El mensaje no se modificó.
El remitente del mensaje (Alice) es auténtico.
Para que este sistema funcione, Alicia debe ocultar el valor hash original a todos excepto a Roberto.
Alice envía el mensaje de texto no cifrado a Bob a través de un canal público no seguro y coloca el mensaje hash en su sitio web visible públicamente.
Este método evita la manipulación de mensajes evitando que cualquier usuario modifique el valor hash. Aunque cualquier persona puede leer el mensaje y su hash, solo Alice puede cambiar el valor del hash. Un atacante que quiera suplantar a Alice requeriría acceso al sitio web de Alice.
Ninguno de los métodos anteriores impedirá que alguien lea los mensajes de Alice, ya que se transmiten en texto no cifrado. Normalmente, la seguridad completa requiere firmas digitales (firma de mensajes) y cifrado.
.NET proporciona las siguientes clases que implementan algoritmos hash:
.NET también proporciona MD5 y SHA1. Pero se han encontrado que los algoritmos MD5 y SHA-1 no son seguros, y ahora se recomienda SHA-2. SHA-2 incluye SHA256, SHA384 y SHA512.
Generación de números aleatorios
La generación aleatoria de números es integral para muchas operaciones criptográficas. Por ejemplo, las claves criptográficas deben ser lo más aleatorias posible para que sea inviable reproducirlas. Los generadores de números aleatorios criptográficos deben generar una salida que sea computacionalmente inviable para predecir con una probabilidad superior a la mitad. Por lo tanto, cualquier método de predicción del siguiente bit de salida no debe funcionar mejor que la estimación aleatoria. Las clases de .NET usan generadores de números aleatorios para generar claves criptográficas.
La RandomNumberGenerator clase es una implementación de un algoritmo de generador de números aleatorios.
Manifiestos ClickOnce
Las siguientes clases de criptografía permiten obtener y comprobar información sobre las firmas de manifiesto para las aplicaciones que se implementan mediante la tecnología ClickOnce:
La clase ManifestSignatureInformation obtiene información sobre una firma de manifiesto cuando se utiliza la sobrecarga de su método VerifySignature .
Puede usar la ManifestKinds enumeración para especificar qué manifiestos se van a comprobar. El resultado de la comprobación es uno de los SignatureVerificationResult valores de enumeración.
La clase ManifestSignatureInformationCollection proporciona una colección de objetos ManifestSignatureInformation de solo lectura de las firmas comprobadas.
Además, las siguientes clases proporcionan información de firma específica:
StrongNameSignatureInformation contiene información sobre la firma de nombre seguro de un manifiesto.
AuthenticodeSignatureInformation representa la información de firma Authenticode para un manifiesto.
TimestampInformation contiene información sobre la marca de tiempo en una firma Authenticode.
TrustStatus proporciona una manera sencilla de comprobar si una firma Authenticode es de confianza.
Clases de criptografía de próxima generación (CNG)
Las clases de Criptografía de próxima generación (CNG) proporcionan un contenedor administrado en torno a funciones CNG nativas. (CNG es el reemplazo de CryptoAPI). Estas clases tienen "Cng" como parte de sus nombres. La clase contenedora de claves CngKey es fundamental en estas clases contenedoras CNG, pues abstrae el almacenamiento y el uso de claves CNG. Esta clase le permite almacenar un par de claves o una clave pública de forma segura y hacer referencia a ella mediante un nombre de cadena simple. La clase de firma basada en curva elíptica ECDsaCng y la clase de cifrado ECDiffieHellmanCng pueden usar objetos CngKey.
La CngKey clase se usa para una variedad de operaciones adicionales, como abrir, crear, eliminar y exportar claves. También proporciona acceso al identificador de clave subyacente para usarlo al llamar directamente a funciones nativas.
.NET también incluye una variedad de clases de CNG compatibles, como las siguientes:
CngProvider mantiene un proveedor de almacenamiento de claves.
CngAlgorithm mantiene un algoritmo CNG.
CngProperty mantiene las propiedades de clave usadas con frecuencia.
Consulte también
- Modelo de criptografía : describe cómo se implementa la criptografía en la biblioteca de clases base.
- Criptografía multiplataforma
- Vulnerabilidades de tiempo con descifrado simétrico en modo CBC al usar el relleno
- protección de datos de ASP.NET Core