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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
static
void
Main
(
string
[]
args)
{
// À 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 :
|
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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
static
void
Main
(
string
[]
args)
{
// Cet 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 :
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. |
SHA-2 |
Version 512 bits : SHA512Managed, SHA512CryptoServiceProvider, SHA512Cng. |
Exemple 3 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
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 :
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.