Codes d’authentification des messages, hachages et signatures
Cet article explique comment les codes d’authentification des messages (MAC), les hachages et les signatures peuvent être utilisés dans les applications plateforme Windows universelle (UWP) pour détecter la falsification des messages.
Codes d’authentification des messages (MAC)
Le chiffrement permet d’empêcher un individu non autorisé de lire un message, mais il n’empêche pas cette personne de falsifier le message. Un message modifié, même si l’altération n’entraîne rien de non-sens, peut avoir des coûts réels. Un code d’authentification de message (MAC) permet d’empêcher la falsification des messages. Par exemple, examinez le scénario suivant :
- Bob et Alice partagent une clé secrète et acceptent une fonction MAC à utiliser.
- Bob crée un message et entre le message et la clé secrète dans une fonction MAC pour récupérer une valeur MAC.
- Bob envoie le message [non chiffré] et la valeur MAC à Alice sur un réseau.
- Alice utilise la clé secrète et le message comme entrée dans la fonction MAC. Elle compare la valeur MAC générée à la valeur MAC envoyée par Bob. S’ils sont identiques, le message n’a pas été modifié en transit.
Notez que Eve, une écoute par un tiers sur la conversation entre Bob et Alice, ne peut pas manipuler efficacement le message. Eve n’a pas accès à la clé privée et ne peut donc pas créer une valeur MAC qui rendait le message falsifié légitime pour Alice.
La création d’un code d’authentification de message garantit uniquement que le message d’origine n’a pas été modifié et, à l’aide d’une clé secrète partagée, que le hachage de message a été signé par une personne ayant accès à cette clé privée.
Vous pouvez utiliser MacAlgorithmProvider pour énumérer les algorithmes MAC disponibles et générer une clé symétrique. Vous pouvez utiliser des méthodes statiques sur la classe EncryptionEngine pour effectuer le chiffrement nécessaire qui crée la valeur MAC.
Les signatures numériques sont l’équivalent de la clé publique des codes d’authentification de message de clé privée (MAC). Bien que les macs utilisent des clés privées pour permettre à un destinataire de message de vérifier qu’un message n’a pas été modifié pendant la transmission, les signatures utilisent une paire de clés privée/publique.
Cet exemple de code montre comment utiliser la classe MacAlgorithmProvider pour créer un code d’authentification de message haché (HMAC).
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
namespace SampleMacAlgorithmProvider
{
sealed partial class MacAlgProviderApp : Application
{
public MacAlgProviderApp()
{
// Initialize the application.
this.InitializeComponent();
// Initialize the hashing process.
String strMsg = "This is a message to be authenticated";
String strAlgName = MacAlgorithmNames.HmacSha384;
IBuffer buffMsg;
CryptographicKey hmacKey;
IBuffer buffHMAC;
// Create a hashed message authentication code (HMAC)
this.CreateHMAC(
strMsg,
strAlgName,
out buffMsg,
out hmacKey,
out buffHMAC);
// Verify the HMAC.
this.VerifyHMAC(
buffMsg,
hmacKey,
buffHMAC);
}
void CreateHMAC(
String strMsg,
String strAlgName,
out IBuffer buffMsg,
out CryptographicKey hmacKey,
out IBuffer buffHMAC)
{
// Create a MacAlgorithmProvider object for the specified algorithm.
MacAlgorithmProvider objMacProv = MacAlgorithmProvider.OpenAlgorithm(strAlgName);
// Demonstrate how to retrieve the name of the algorithm used.
String strNameUsed = objMacProv.AlgorithmName;
// Create a buffer that contains the message to be signed.
BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, encoding);
// Create a key to be signed with the message.
IBuffer buffKeyMaterial = CryptographicBuffer.GenerateRandom(objMacProv.MacLength);
hmacKey = objMacProv.CreateKey(buffKeyMaterial);
// Sign the key and message together.
buffHMAC = CryptographicEngine.Sign(hmacKey, buffMsg);
// Verify that the HMAC length is correct for the selected algorithm
if (buffHMAC.Length != objMacProv.MacLength)
{
throw new Exception("Error computing digest");
}
}
public void VerifyHMAC(
IBuffer buffMsg,
CryptographicKey hmacKey,
IBuffer buffHMAC)
{
// The input key must be securely shared between the sender of the HMAC and
// the recipient. The recipient uses the CryptographicEngine.VerifySignature()
// method as follows to verify that the message has not been altered in transit.
Boolean IsAuthenticated = CryptographicEngine.VerifySignature(hmacKey, buffMsg, buffHMAC);
if (!IsAuthenticated)
{
throw new Exception("The message cannot be verified.");
}
}
}
}
Codes de hachage
Une fonction de hachage de chiffrement prend un bloc de données arbitrairement long et retourne une chaîne de bits de taille fixe. Les fonctions de hachage sont généralement utilisées lors de la signature de données. Étant donné que la plupart des opérations de signature de clé publique sont gourmandes en calcul, il est généralement plus efficace de signer (chiffrer) un hachage de message qu’il s’agit de signer le message d’origine. La procédure suivante représente un scénario courant, même s’il est simplifié :
- Bob et Alice partagent une clé secrète et acceptent une fonction MAC à utiliser.
- Bob crée un message et entre le message et la clé secrète dans une fonction MAC pour récupérer une valeur MAC.
- Bob envoie le message [non chiffré] et la valeur MAC à Alice sur un réseau.
- Alice utilise la clé secrète et le message comme entrée dans la fonction MAC. Elle compare la valeur MAC générée à la valeur MAC envoyée par Bob. S’ils sont identiques, le message n’a pas été modifié en transit.
Notez qu’Alice a envoyé un message non chiffré. Seul le hachage a été chiffré. La procédure garantit uniquement que le message d’origine n’a pas été modifié et, à l’aide de la clé publique d’Alice, que le hachage de message a été signé par une personne ayant accès à la clé privée d’Alice, probablement Alice.
Vous pouvez utiliser la classe HashAlgorithmProvider pour énumérer les algorithmes de hachage disponibles et créer une valeur CryptographicHash.
Les signatures numériques sont l’équivalent de la clé publique des codes d’authentification de message de clé privée (MAC). Alors que les macs utilisent des clés privées pour permettre à un destinataire de message de vérifier qu’un message n’a pas été modifié pendant la transmission, les signatures utilisent une paire de clés privée/publique.
L’objet CryptographicHash peut être utilisé pour hacher plusieurs fois des données différentes sans avoir à recréer l’objet pour chaque utilisation. La méthode Append ajoute de nouvelles données à une mémoire tampon à hacher. La méthode GetValueAndReset hache les données et réinitialise l’objet pour une autre utilisation. Cet exemple est illustré par l’exemple suivant.
public void SampleReusableHash()
{
// Create a string that contains the name of the hashing algorithm to use.
String strAlgName = HashAlgorithmNames.Sha512;
// Create a HashAlgorithmProvider object.
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
// Create a CryptographicHash object. This object can be reused to continually
// hash new messages.
CryptographicHash objHash = objAlgProv.CreateHash();
// Hash message 1.
String strMsg1 = "This is message 1.";
IBuffer buffMsg1 = CryptographicBuffer.ConvertStringToBinary(strMsg1, BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg1);
IBuffer buffHash1 = objHash.GetValueAndReset();
// Hash message 2.
String strMsg2 = "This is message 2.";
IBuffer buffMsg2 = CryptographicBuffer.ConvertStringToBinary(strMsg2, BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg2);
IBuffer buffHash2 = objHash.GetValueAndReset();
// Hash message 3.
String strMsg3 = "This is message 3.";
IBuffer buffMsg3 = CryptographicBuffer.ConvertStringToBinary(strMsg3, BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg3);
IBuffer buffHash3 = objHash.GetValueAndReset();
// Convert the hashes to string values (for display);
String strHash1 = CryptographicBuffer.EncodeToBase64String(buffHash1);
String strHash2 = CryptographicBuffer.EncodeToBase64String(buffHash2);
String strHash3 = CryptographicBuffer.EncodeToBase64String(buffHash3);
}
Signatures numériques
Les signatures numériques sont l’équivalent de la clé publique des codes d’authentification de message de clé privée (MAC). Alors que les macs utilisent des clés privées pour permettre à un destinataire de message de vérifier qu’un message n’a pas été modifié pendant la transmission, les signatures utilisent une paire de clés privée/publique.
Étant donné que la plupart des opérations de signature de clé publique sont gourmandes en calcul, il est généralement plus efficace de signer (chiffrer) un hachage de message qu’il est de signer le message d’origine. L’expéditeur crée un hachage de message, le signe et envoie à la fois la signature et le message (non chiffré). Le destinataire calcule un hachage sur le message, déchiffre la signature et compare la signature déchiffrée à la valeur de hachage. S’ils correspondent, le destinataire peut être assez certain que le message a, en fait, provient de l’expéditeur et n’a pas été modifié pendant la transmission.
La signature garantit uniquement que le message d’origine n’a pas été modifié et, à l’aide de la clé publique de l’expéditeur, que le hachage de message a été signé par une personne ayant accès à la clé privée.
Vous pouvez utiliser un objet AsymmetricKeyAlgorithmProvider pour énumérer les algorithmes de signature disponibles et générer ou importer une paire de clés. Vous pouvez utiliser des méthodes statiques sur la classe CryptographicHash pour signer un message ou vérifier une signature.