La cryptographie en C#

Daniel MINKO FASSINOU

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

Pour réagir au contenu de ce tutoriel, un espace de dialogue vous est proposé sur le forum. Commentez

- Titre : La cryptographie en C#

- Auteur : Daniel MINKO FASSINOU

- Parution : 22 novembre 2016

- Licence :

Sommaire

- I. Généralités

- II. Le chiffrage symétrique

- II-A. Principales propriétés de cette classe

- II-B. Principales méthodes de cette classe

- III. Le chiffrage asymétrique

- IV. Hachage

- IV-A. Principales méthodes de cette classe

- IV-A-1. Algorithmes de hachage implémentés en .NET

- V. Conclusion

- VI. Remerciements

I - 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'algorithmes de chiffrement :

- symétrique : une même clé est utilisée pour chiffrer et déchiffrer les messages ;

- asymétriques : 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 RijndaelManaged implé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ésente uniquement sur les anciens systèmes.

- Les classes de l'API CNG (Cryptography Next Generation). C'est la nouvelle 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).

II - Le chiffrage symétrique

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

II-A - 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ée 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.

II-B - 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 nouvel IV ;

- void GenerateKey() : génère une nouvelle clé.

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

Algorithmes

Classes

AES

AesManaged, AesCryptoServiceProvider

DES

AesManaged, AesCryptoServiceProvider

RC2

RC2CryptoServiceProvider

Rijndael

RijndaelManaged

TripleDES

TripleDESCryptoServiceProvider

Exemple 1 :

1. static void Main(string[] args)

2. {

3. // À la création de l'instance de chiffrage, la clé et le IV sont également créés

4. TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

6. byte[] iv = TDES.IV;

7. byte[] key = TDES.Key;

9. string text = "texte en clair";

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

13. // La même clé et le même IV sont utilisés pour le chiffrage et le déchiffrage

14. byte[] cryptedTextAsByte = Crypt(text, key, iv);

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

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

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

21. }

23. static byte[] Crypt(string text, byte[] key, byte[] iv)

24. {

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

27. TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

29. // Cet objet est utilisé pour chiffrer les données.

30. // Il reçoit en entrée les données en clair sous la forme d'un tableau de bytes.

31. // Les données chiffrées sont également retournées sous la forme d'un tableau de bytes

32. var encryptor = TDES.CreateEncryptor(key, iv);

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

36. return cryptedTextAsByte;

37. }

39. static string Decryp(byte[] cryptedTextAsByte, byte[] key, byte[] iv)

40. {

41. TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();

43. // Cet objet est utilisé pour déchiffrer les données.

44. // Il reçoit les données chiffrées sous la forme d'un tableau de bytes.

45. // Les données déchiffrées sont également retournées sous la forme d'un tableau de bytes

46. var decryptor = TDES.CreateDecryptor(key, iv);

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

50. return Encoding.Default.GetString(decryptedTextAsByte);

51. }

Résultat de l'exécution :

III - 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

Classes

DSA

DSACryptoServiceProvider

ECDiffieHellman Elliptic Curve Diffie-Hellman

ECDiffieHellmanCng

ECDsa Elliptic Curve Digital Signature Algorithm (ECDSA)

ECDsaCng

RSA

RSACryptoServiceProvider

Exemple 2 :

1. static void Main(string[] args)

2. {

3. // Cet objet est utilisé par le service de chiffrement

4. // pour créer les clés

5. CspParameters cspParams = new CspParameters();

7. // Les clés publique et privée

8. RSAParameters privateKeys;

9. RSAParameters publicKeys;

11. using (var rsa = new RSACryptoServiceProvider(cspParams))

12. {

13. // Génère la clé publique et la clé privée

14. privateKeys = rsa.ExportParameters(true);

15. publicKeys = rsa.ExportParameters(false);

17. rsa.Clear();

18. }

20. string texte = "Allo le monde";

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

24. // La clé publique est utilisée pour chiffrer les données

25. byte[] cryptedBytes = Encrypt(texte, publicKeys);

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

29. // La clé privée est utilisée pour déchiffrer les données

30. Console.WriteLine("Text déchiffré {0}", Decrypt(cryptedBytes, privateKeys));

31. }

33. static byte[] Encrypt(string value, RSAParameters rsaKeyInfo)

34. {

35. using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

36. {

37. // Récupère les infos de la clé publique

38. rsa.ImportParameters(rsaKeyInfo);

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

42. // Chiffre les données.

43. // Les données chiffrées sont retournées sous la forme d'un tableau de bytes

44. byte[] encryptedData = rsa.Encrypt(encodedData, true);

46. rsa.Clear();

48. return encryptedData;

49. }

50. }

52. static string Decrypt(byte[] encryptedData, RSAParameters rsaKeyInfo)

53. {

54. using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

55. {

56. // Récupère les infos de la clé privée

57. rsa.ImportParameters(rsaKeyInfo);

59. // Déchiffre les données.

60. // Les données déchiffrées sont retournées sous la forme d'un tableau de bytes

61. byte[] decryptedData = rsa.Decrypt(encryptedData, true);

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

65. rsa.Clear();

67. return decryptedValue;

68. }

69. }

Résultat de l'exécution :

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

IV - 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 hachage héritent de la classe abstraite System.Security.Cryptography.HashAlgorithm.

IV-A - Principales méthodes de 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.

IV-A-1 - Algorithmes de hachage implémentés en .NET

Algorithmes

Classes

MD5

MD5CryptoServiceProvider, MD5Cng.

SHA-1

SHA1Managed, SHA1CryptoServiceProvider, SHA1Cng.
Proposée en hash de plusieurs tailles : 224, 256, 384 et 512 bits.

SHA-2

Version 512 bits : SHA512Managed, SHA512CryptoServiceProvider, SHA512Cng.

Exemple 3 :

1. static void Main(string[] args)

2. {

3. 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.";

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

7. SHA512 sha512 = SHA512Cng.Create();

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

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

12. }

Résultat de l'exécution :

V - 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.

VI - Remerciements

Nous remercions la société Soat qui nous a autorisés à publier ce tutoriel.

Nous tenons également à remercier f-leb pour la relecture orthographique, et Malick SECK pour la mise au gabarit.