Servicios criptográficos de .NET Framework

Introducción

.NET Framework incluye un conjunto de servicios criptográficos que amplían servicios similares de Windows a través de CryptoAPI . El espacio de nombres System.Security.Cryptography brinda acceso programático a una amplia variedad de servicios criptográficos que las aplicaciones pueden usar para cifrar y descifrar datos , garantizar la integridad de los datos y procesar firmas y certificados digitales.

Criptografía de espacio de nombres

En el nivel más alto, el espacio de nombres de criptografía se puede dividir en cuatro partes principales (Tabla 1). El objetivo principal de este espacio es proporcionar a las clases algoritmos para operaciones como el cifrado y el hashing. Estos algoritmos se implementan sobre la base de un patrón extensible (patrón), que incluye dos niveles de herencia.

En la parte superior de la jerarquía hay una clase base abstracta (como AsymmetricAlgorithm o HashAlgorithm) cuyo nombre corresponde al tipo de algoritmo. De tal clase, se hereda una clase abstracta de segundo nivel que proporciona una interfaz pública para usar este algoritmo. Por ejemplo, SHA1 (Secure Hash Algorithm) es una clase derivada de HashAlgorithm y contiene métodos y propiedades específicos del algoritmo SHA1. Finalmente, la implementación del propio algoritmo se deriva de la clase de segundo nivel; es su instancia la que crea y utiliza la aplicación cliente. En este nivel, la implementación puede ser administrada, no administrada o ambas.

Elemento Descripción
Algoritmos de cifrado Un conjunto de clases que se utiliza para implementar algoritmos de cifrado y hash simétricos y asimétricos.
clases de ayuda Clases que proporcionan generación de números aleatorios, transformaciones, interacción con el almacenamiento de CryptoAPI y cifrado en sí mismo basado en el modelo de transmisión.
Certificados X.509 Clases definidas en el espacio de nombres System.Security.Сryptograph. X509 Certificados y certificados digitales que representan
Firmas digitales XML Clases definidas en el espacio de nombres System.Cryptography.Xml que representan firmas digitales en documentos XML

Pestaña. 1. Elementos básicos del espacio de nombres de criptografía

Las implementaciones no administradas generalmente tienen el sufijo "CryptoServiceProvider" (por ejemplo, SHA1CryptoServiceProvider) para indicar que la implementación en realidad la proporciona un proveedor de servicios criptográficos ( CSP ) que está instalado en el nivel del sistema operativo y actúa como un contenedor CryptoAPI .

Los nombres de implementación administrados incluyen el sufijo "Administrado" (por ejemplo, SHA1Managed). Dichas implementaciones no se basan en CryptoAPI y solo contienen código administrado.

Al instanciar una de las clases concretas, los constructores originales siempre establecen los parámetros del objeto en valores razonables y seguros (si es posible). Así, los algoritmos de cifrado asimétrico basados ​​en criptografía de clave pública generan un par de claves aleatorias, y los algoritmos de cifrado simétrico generan una clave aleatoria y un vector de inicialización (IV); sin embargo, ajustan automáticamente propiedades como Modo y Relleno. Además, los algoritmos del segundo tipo intentan utilizar valores "persistentes" por defecto.

El segundo conjunto principal de clases en el espacio de nombres System.Security.Cryptography incluye las clases que realmente se usan en el proceso de encriptación y desencriptación de datos, así como varias clases auxiliares . Este espacio de nombres contiene, por ejemplo, la clase abstracta RandomNumberGenerator, de la que se heredan las clases RNGCryptoServiceProvider, ToBase64Transform y FromBase64Transform (utilizadas en las transformaciones de datos correspondientes).

El espacio de nombres de criptografía no solo proporciona algoritmos de cifrado, sino que también contiene un espacio de nombres secundario, X509Certificates. Este último combina solo tres clases diseñadas para operaciones con certificados Authenticode X.509 v.3. La clase X509Certificate proporciona los métodos estáticos CreateFromCertFile y CreateFromSignedFile para instanciar un certificado:

X509Certificate c = X509Certificate.CreateFromCertFile("myCert.cer"); Console.WriteLine(c.GetName); Console.WriteLine(c.GetPublicKeyString); Console.WriteLine(c.GetSerialNumberString); Console.WriteLine(c.GetExpirationDateString);

El espacio de nombres de criptografía también tiene un espacio de nombres secundario , XML , que es utilizado por el sistema de seguridad de .NET Framework para firmar digitalmente objetos XML de acuerdo con el borrador de la especificación WSC para procesamiento y sintaxis de firma XML ( http://www.w3.org/ TR/ 2000/WD-xmldsig-core-20000228/ ).

Algoritmos de cifrado

Algoritmos simétricos

Hay varias formas de formar cifrados de bloque. La forma más sencilla e intuitiva es dividir el texto de origen en bloques del tamaño adecuado y luego someter cada bloque por separado a una transformación de cifrado. Este modo de utilizar cifrados de bloque se denomina libro de códigos electrónico (ECB). Su principal inconveniente es que los mismos bloques de texto sin formato cuando se cifran darán los mismos bloques de texto cifrado, y esto puede facilitar enormemente la tarea de descifrado del adversario. Por lo tanto, el modo ECB no se recomienda para cifrar textos de más de un bloque. En tales casos, es mejor usar uno de los modos que conectan diferentes bloques entre sí.

De forma predeterminada, CryptoAPI utiliza cifrados de bloques en el modo de encadenamiento de bloques de cifrado (CBC). En este modo, durante el cifrado, el siguiente bloque del texto sin formato se combina primero con el bloque anterior del texto cifrado (usando un XOR bit a bit), y luego la secuencia de bits resultante se ingresa al cifrado de bloque. El bloque de texto cifrado resultante se utiliza para cifrar el siguiente bloque. El primer bloque de texto sin formato también debe combinarse con alguna secuencia de bits, pero todavía no existe un "bloque de texto cifrado anterior"; por lo tanto, los modos de cifrado de circuito cerrado requieren el uso de un parámetro más: se denomina vector de inicialización (IV - vector de inicialización). IV es un valor binario no secreto, cuyo tamaño es igual a la longitud del bloque de cifrado. Para generar una nueva clave, debe llamar al método GenerateKey y, para el vector de inicialización, al método GenerateIV. Por ejemplo, para el algoritmo RC2 compatible con el proveedor criptográfico subyacente de Microsoft , el tamaño del bloque es de 64 bits (8 bytes).

DESCryptoServiceProvider mDES; mDES = nuevo DESCryptoServiceProvider(); // Generar nueva clave y IV al azar mDES.GenerateKey(); mDES.GenerateIV();

Algoritmo simétrico
|— AES
| |— AESCryptoServiceProvider
| |— Administrado por AES
|— DES
| |— DESCryptoServiceProvider
|— RC2
| |— RC2CryptoServiceProvider
|— Rijndael
| |— RijndaelAdministrado
|— TripleDES
| |— TripieDESCryptoServiceProvider
Jerarquía de algoritmos simétricos

SymmetricAlgorithm es una clase base abstracta de la que heredan otras clases específicas de algoritmo . Los algoritmos simétricos admitidos incluyen el estándar de cifrado de datos (DES), RC2, Rijndael, el estándar de cifrado avanzado (AES) y el estándar de cifrado de datos triple (TripleDES). Cada algoritmo incluye una clase abstracta derivada de SymmetricAlgorithm, como DES, y una clase de proveedor de servicios o administrada derivada de la base, como DESCryptoServiceProvider. Las propiedades KeySize y BlockSize le permiten definir la longitud de la clave y el tamaño del bloque de datos (en bits) que se puede cifrar o descifrar en una sola operación.

Usando la clase RijndaelManaged:

RijndaelManaged oEnc = new RijndaelManaged(); ent yo; StringstrKey = String.Empty; CadenastrlV = Cadena.Vacío; for(i = 0; i < (oEnc.KeySize / 8); i++) strKey += oEnc.Key(i).ToString() + " "; for(i = 0; i < (oEnc.BlockSize / 8); i++) strlV += oEnc.lV(i).ToString() + " "; Consola.WriteLine(strKey); Consola.WriteLine(strIV); Console.WriteLine(oEnc.KeySize.Tostring()); Console.WriteLine(oEnc.BlockSize.Tostring());

.NET Framework admite un modelo de programación basado en secuencias. Las clases de flujo , derivadas de System.lO.Stream, representan datos de varios almacenes (archivos de texto, documentos XML , mensajes MSMQ , memoria y red) y le permiten leer datos o escribir en los almacenes correspondientes. Esta funcionalidad se basa en la clase CryptoStream, que se deriva de System.IO.Stream y sirve como modelo de flujo para transformaciones criptográficas.

DESCryptoServiceProvider mDES = nuevo DESCryptoServiceProvider(); FileStream fsOutput = new FileStream("temp.dat", FileMode.Create, FileAccess.Write); Byte[] arInput = new Byte[320]; //… // Crear un DES Encryptor a partir de esta instancia ICryptoTransform desEncript = mDES.CreateEncryptor(); // Crea un CryptoStream que convierte el flujo de archivos // usando encriptación DES CryptoStream sCrypto = new CryptoStream(fsOutput, desEncrypt, CryptoStreamMode.Write); // Escribir el archivo encriptado sCrypto.Write(arInput, 0, arInput.longitud); sCrypto.Close(); fsOutput.Close();

El cifrado asimétrico se usa para cifrar pequeñas cantidades de datos, por lo que CryptoStream no se usa con el cifrado asimétrico.

Cifrado asimétrico (cifrado de clave pública)

Los algoritmos asimétricos bien conocidos incluyen el algoritmo de firma digital (DSA) y RSA. Estos algoritmos se derivan en última instancia de las clases abstractas DSA y RSA, que a su vez se derivan de AsymmetricAlgorithm. Debido a que estos algoritmos son muy complejos, necesitan clases auxiliares derivadas, por ejemplo, de AsymmetricKeyExchangeFormatter y AsymmetricSignatureFormatter.

Algoritmo asimétrico
|— DSA
| |— DSACryptoServiceProvider
|— RSA
| |—RSACryptoServiceProvider

AsymmetricKeyExchangeFormatter
|— RSAOAEPKeyExchangeFormatter
|— RSAPKCS1KeyExchangeFormatter

AsimétricaKeyExchangeDeformatter
|— RSAOAEPKeyExchangeDeformatter
|— RSAPKCS1KeyExchangeDeformatter

AsymmetricKeySignatureFormatter
|—RSAOAEPSsignatureFormatter
| —RSAPKCS1SignatureFormatter

AsymmetricSignatureDeformatter
|— RSAOAEPSignatureDeformatter
|— RSAPKCS1SignatureDeformatter
Jerarquía de algoritmos asimétricos

No solo puede permitir que el constructor del algoritmo asimétrico original genere un par de claves, sino que también puede recuperar un par de claves ya existente de la tienda respaldada por CSP .

CspParameters cp = new CspParameters(); cp.KeyContainerName = ContainerName; RSACryptoServiceProvider rsa = nuevo RSACryptoServiceProvider(cp);

Intercambio de claves simétricas

Las clases RSAOAEPKeyExchangeFormatter/Deformatter y RSAPKCS1KeyExchangeFormatter/Deformatter son responsables del intercambio de claves de sesión en .NET . Se derivan de las clases base AsymmetricKeyExchangeFormatter/Deformatter, que proporcionan los métodos CreateKeyExchange y DecryptKeyExchange para cifrar y descifrar claves de sesión, respectivamente.

RSACryptoServiceProvider rsa1 = nuevo RSACryptoServiceProvider(1024); // destinatario clave RSAParameters rp = rsa1.ExportParameters(falso); Console.WriteLine("Pasando la clave pública al remitente..."); // pasar la clave pública al remitente //… RSACryptoServiceProvider rsa2 = nuevo RSACryptoServiceProvider(1024); // remitente clave Console.WriteLine("Importando la clave pública del receptor..."); // importa la clave pública del destinatario rsa2.ImportParameters(rp); AsymmetricKeyExchangeFormatter kf = (AsymmetricKeyExchangeFormatter) new RSAOAEPKeyExchangeFormatter(rsa2); byte[] clave = new Byte[16]; // clave de 128 bits byte[] enckey = kf.CreateKeyExchange(clave); Console.WriteLine("Enviando clave de sesión cifrada al receptor..."); // pasar la clave de sesión cifrada al destinatario //… AsimétricaKeyExchangeDeformatter kd = (AsymmetricKeyExchangeDeformatter) new RSAOAEPKeyExchangeDeformatter(rsa1); // Descifrar la clave byte[] deckey = kd.DecryptKeyExchange(enckey); for(int i = 0; i < 16 ; i++) if (deckey[i] != key[i]) { Console.WriteLine(" Intercambio de clave fallido"); } Console.WriteLine(" Intercambio de clave exitoso");

Algoritmos hash

El espacio de nombres Cryptography contiene la clase base HashAlgorithm y las clases derivadas que admiten los algoritmos MD5 , SHA1 , SHA256 , SHA384 y SHA512 . El algoritmo MD5 da un hash de 128 bits , mientras que SHA1 da un  hash de 160 bits. Los números en los nombres de otras versiones de algoritmos SHA corresponden a la longitud de los hash que crean. Cuanto mayor sea el hash , más fiable será el algoritmo y más difícil de descifrar. Todos estos algoritmos se implementan en dos versiones: basados ​​en código administrado y no administrado.


Algoritmo hash | —Algoritmo hash con clave
| |— HMACSHA1
| |— MACTripleDES
|— MD5
| |— MD5CryptoServiceProvider
|— SHA1
| |— SHA1CryptoServiceProvider
| |— SHA1Gestionado
|— SHA256
| |— SHA256Gestionado
|— SHA384
| |— SHA384Gestionado
|— SHA512
| |— SHA512
Jerarquía administrada de algoritmos hash

Para calcular el resumen , solo necesita crear una instancia de la clase de algoritmo hash y llamar a su método ComputeHash sobrecargado, que hereda de HashAlgorithm:

FileStream fsData = new FileStream("mydata.txt",FileHode.Open, FileAccess.Read); Resumen de bytes[]; SHA512Managed oSHA = new SHA512Managed(digest - oSHA.ComputeHash(fsData)); fsKey.Cerrar()

Aquí, al método ComputeHash se le pasa un objeto Stream, pero también acepta una matriz de bytes. El espacio de nombres Cryptography también tiene una clase KeyedHashAlgorithm abstracta . Los algoritmos implementados en las clases HMACSHA1 y MACTripleDES, derivados de KeyedHashAlgorithm, permiten generar un Message Authentication Code ( MAC ). Con el MAC, puede determinar si los datos transmitidos a través de un canal de comunicación no seguro se han modificado, siempre que tanto el remitente como el destinatario utilicen una clave secreta compartida.

Firma Digital

El método SignHash de las clases RSACryptoServiceProvider y DSACryptoServiceProvider calcula una firma para un hash de datos creado mediante un algoritmo especial. El algoritmo hash se pasa como segundo parámetro como identificador, que se puede calcular mediante la función MapNameToOID. Para RSACryptoServiceProvider, es SHA1 y MD5, y para DSACryptoServiceProvider, solo es SHA1.

rsaCSP.SignHash(hashedData, CryptoConfig.MapNameToOID("SHA1"));

Las clases RSAPKCS1SignatureFormatter/Deformatter y DSASignatureFormatter/Deformatter crean una firma digital . Ambos pares de clases se heredan de las clases AsymmetricSignatureFormatter/Deformatter, que proporcionan una interfaz estándar para crear y verificar una firma digital: los métodos CreateSignature y VerifySignature. Antes de calcular o verificar una firma digital, asegúrese de configurar el algoritmo hash que se usará en el proceso llamando a SetHashAlgorithm. RSAPKCS1SignatureFormatter comprende dos algoritmos hash: MD5 y SHA1, mientras que DSASignatureFormatter, solo SHA1.

// crear firma digital RSA Formateador de firma asimétrica sf; sf = (AsymmetricSignatureFormatter) new RSAPKCS1SignatureFormatter(rsa); // crea un formateador sf.SetHashAlgorithm("MD5"); // selecciona el algoritmo hash sig = sf.CreateSignature(Hash); // crea una firma (el hash ya debe calcularse antes) //verificar firma digital RSA Deformateador de firma asimétrica df; df = (AsimétricoSignatureDeformatter) nuevo RSAPKCS1SignatureDeformatter(rsa); // crea un deformador df.SetHashAlgorithm("MD5"); if (df.VerifySignature(Hash, sig)) // verificar la firma { // la firma es correcta } más { // la firma no es válida }

Véase también

Notas

Literatura

  • Yu. E. Kuptsevich. Almanaque del programador, Volumen 4. Seguridad en Microsoft .NET. - M. : Casa editorial y comercial "Edición rusa", 2004. - 304 p. - ISBN 5-7502-0184-8.

Enlaces