Accueil Nos publications Blog La cryptographie en C#

La cryptographie en C#

Cryptographie en C#

Le but de cet article est de présenter les classes implémentant la cryptographie en C#. Découvrons comment la cryptographie, le hachage sont définis dans ce langage.

Généralités

Petit rappel : la cryptographie désigne l’ensemble des techniques utilisées pour chiffrer un message. Il existe deux types d’algorithme de chiffrement :

  • symétrique : une même clé est utilisée pour chiffrer et déchiffrer les messages
  • asymétrique : il existe une clé publique pour le chiffrement et une clé privée pour déchiffrer les messages

En .NET, trois grandes familles de classes implémentent la cryptographie :

  • Les classes managées. Leurs noms se terminent en Managed. Par exemple, la classe RijndaelManagedimplémente l’algorithme Rijndael.
  • Les classes issues de l’API de cryptographie de Microsoft CAPI. Leur suffixe est CryptoServiceProvider. Exemple: la classe DESCryptoServiceProvider implémente l’algorithme DES. Cette API n’évolue plus et est présent uniquement sur les anciens systèmes.
  • Les classes de l’API CNG (Cryptography Next Generation). C’est le nouvel API de cryptographie disponible à partir de Windows Vista. Ses classes se terminent en Cng. Exemple, la classe ECDiffieHellmanCng qui implémente l’algorithme ECDH (Elliptic Curve Diffie-Hellman).

Le chiffrage symétrique

Toutes les classes implémentant les algorithmes symétriques héritent de la classe System.Security.Cryptography.SymmetricAlgorithm.

Principales propriétés de cette classe

  • IV (Byte[]) : le vecteur d’initialisation utilisée pour chiffrer et déchiffrer les données
  • Key (Byte[]) : la clé utilisé pour le chiffrage et le déchiffrage

Le chiffrage symétrique nécessite une clé et un vecteur d’initialisation (IV) pour chiffrer et déchiffrer les données. En utilisant le constructeur par défaut, ces deux propriétés sont automatiquement créées.

Principales méthodes de cette classe :

  • void Clear() : libère les ressources utilisées par l’objet
  • ICryptoTransform CreateDecryptor(Byte[], Byte[]) : crée l’objet de déchiffrage à l’aide de la clé et du IV
  • ICryptoTransform CreateEncryptor(Byte[], Byte[]) : crée l’objet de chiffrage à l’aide de la clé et du IV
  • void GenerateIV() : génère un nouveau IV
  • void GenerateKey() : génère une nouvelle clé

Le framework .NET implémente cinq algorithmes symétriques :

Algorithmes Classes
AES AesManaged, AesCryptoServiceProvider
DES DESCryptoServiceProvider
RC2 RC2CryptoServiceProvider
Rijndael RijndaelManaged
TripleDES TripleDESCryptoServiceProvider

Exemple : 1

static void Main(string[] args)
{
    // A la création de l'instance de chiffrage, la clé et le IV sont également créés
    TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

    byte[] iv = TDES.IV;
    byte[] key = TDES.Key;

    string text = "texte en clair";

    Console.WriteLine("Mon texte en clair : {0}", text);

    // La même clé et le même IV sont utilisés pour le chiffrage et le déchiffrage
    byte[] cryptedTextAsByte = Crypt(text, key, iv);

    Console.WriteLine("Mon texte chiffré : {0}", Convert.ToBase64String(cryptedTextAsByte));

    String decryptedText = Decryp(cryptedTextAsByte, key, iv);

    Console.WriteLine("Mon texte déchiffré : {0}", decryptedText);
}

static byte[] Crypt(string text, byte[] key, byte[] iv)
{
    byte[] textAsByte = Encoding.Default.GetBytes(text);

    TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

    // Cet objet est utilisé pour chiffrer les données.
    // Il reçoit en entrée les données en clair sous la forme d'un tableau de bytes.
    // Les données chiffrées sont également retournées sous la forme d'un tableau de bytes
    var encryptor = TDES.CreateEncryptor(key, iv);

    byte[] cryptedTextAsByte = encryptor.TransformFinalBlock(textAsByte, 0, textAsByte.Length);

    return cryptedTextAsByte;
}

static string Decryp(byte[] cryptedTextAsByte, byte[] key, byte[] iv)
{
    TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

    // Cet objet est utilisé pour déchiffrer les données.
    // Il reçoit les données chiffrées sous la forme d'un tableau de bytes.
    // Les données déchiffrées sont également retournées sous la forme d'un tableau de bytes
    var decryptor = TDES.CreateDecryptor(key, iv);

    byte[] decryptedTextAsByte = decryptor.TransformFinalBlock(cryptedTextAsByte, 0, cryptedTextAsByte.Length);

    return Encoding.Default.GetString(decryptedTextAsByte);
}

Résultat de l’exécution :
Résultat de l'exécution 1

Le chiffrage asymétrique

Les algorithmes asymétriques sont moins rapides que les algorithmes symétriques. Les classes implémentant les algorithmes asymétriques héritent de la classe System.Security.Cryptography.AsymmetricAlgorithm.

Algorithmes asymétriques implémentées en .NET :

Algorithmes Classes
DSA DSACryptoServiceProvider
ECDiffieHellman Elliptic Curve Diffie-Hellman ECDiffieHellmanCng
ECDsa Elliptic Curve Digital Signature Algorithm (ECDSA) ECDsaCng
RSA RSACryptoServiceProvider

Exemple 2 :

static void Main(string[] args)
{
    // Cette objet est utilisé par le service de chiffrement
    // pour créer les clés
    CspParameters cspParams = new CspParameters();

    // Les clés publique et privée
    RSAParameters privateKeys;
    RSAParameters publicKeys;

    using (var rsa = new RSACryptoServiceProvider(cspParams))
    {
        // Génère la clé publique et la clé privée
        privateKeys = rsa.ExportParameters(true);
        publicKeys = rsa.ExportParameters(false);

        rsa.Clear();
    }

    string texte = "Allo le monde";

    Console.WriteLine("Texte  en clair {0}", texte);

    // La clé publique est utilisée pour chiffrer les données
    byte[] cryptedBytes = Encrypt(texte, publicKeys);

     Console.WriteLine("Texte chiffré {0}", Convert.ToBase64String(cryptedBytes));

    // La clé privée est utilisée pour déchiffrer les données
    Console.WriteLine("Text déchiffré {0}", Decrypt(cryptedBytes, privateKeys));
}

static byte[] Encrypt(string value, RSAParameters rsaKeyInfo)
{
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {
        // Récupère les infos de la clé publique
        rsa.ImportParameters(rsaKeyInfo);

        byte[] encodedData = Encoding.Default.GetBytes(value);

        // Chiffre les données.
        // Les données chiffrées sont retournées sous la forme d'un tableau de bytes
        byte[] encryptedData = rsa.Encrypt(encodedData, true);

        rsa.Clear();

        return encryptedData;
    }
}

static string Decrypt(byte[] encryptedData, RSAParameters rsaKeyInfo)
{
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {
        // Récupère les infos de la clé privée
        rsa.ImportParameters(rsaKeyInfo);

        // Déchiffre les données.
        // Les données déchiffrées sont retournées sous la forme d'un tableau de bytes
        byte[] decryptedData = rsa.Decrypt(encryptedData, true);

        string decryptedValue = Encoding.Default.GetString(decryptedData);

        rsa.Clear();

        return decryptedValue;
    }
}

Résultat de l’exécution :
crytpto_ex_02

En pratique, les algorithmes asymétriques sont utilisés pour échanger les clés de chiffrement symétrique.

Hachage

Impossible de parler de cryptographie, sans parler de hachage. Le hachage est un processus qui, à partir d’une donnée en entrée, produit une chaîne de longueur fixe, l’empreinte.

Les fonctions de hachage sont utilisées par exemple pour permettre l’authentification par mot de passe sans stocker ce dernier. Dans ce cas, on stocke l’empreinte issue du hachage du mot de passe.

En .NET, toutes les classes qui implémentent le hashage héritent de la classe abstraite System.Security.Cryptography.HashAlgorithm.

Principales méthodes cette classe :

  • Byte[] ComputeHash(Byte[]) : calcule le hachage pour le tableau de bytes en paramètre
  • void Clear() : libère les ressources de l’objet

Algorithmes de hachage implémentés en .NET :

Algorithmes Classes
MD5 MD5CryptoServiceProvider, MD5Cng
SHA-1 SHA1Managed, SHA1CryptoServiceProvider, SHA1Cng
SHA-2 Proposée en hash de plusieurs tailles : 224, 256, 384 et 512 bits.
Version 512 bits : SHA512Managed,SHA512CryptoServiceProvider , SHA512Cng

Exemple 3 :

static void Main(string[] args)
{
    string texte = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

    byte[] textAsByte = Encoding.Default.GetBytes(texte);

    SHA512 sha512 = SHA512Cng.Create();

    byte[] hash = sha512.ComputeHash(textAsByte);

    Console.WriteLine("Hash = {0}", Convert.ToBase64String(hash));
}

Résultat de l’exécution :
Résultat de l'exécution 3

Conclusion

Cet article vous a permis de voir les classes implémentant la cryptographie en .NET. La cryptographie évolue, de nouveaux algorithmes sont régulièrement créés. Microsoft recommande les algorithmes suivants : AES pour la protection des données, HMACSHA256 pour leur intégrité, RSA pour les signatures numériques et l’échange de clés.