Codes d’authentification des messages, hachages et signaturesMACs, hashes, and signatures

Cet article explique comment les codes d’authentification de message (MAC), les codes de hachage et les signatures peuvent être utilisés dans les applications UWP pour détecter une falsification des messages.This article discusses how message authentication codes (MACs), hashes, and signatures can be used in Universal Windows Platform (UWP) apps to detect message tampering.

Codes d’authentification des messagesMessage authentication codes (MACs)

Le chiffrement permet d’empêcher un individu non autorisé de lire un message, mais il n’empêche pas cet individu de le falsifier.Encryption helps prevent an unauthorized individual from reading a message, but it does not prevent that individual from tampering with the message. Un message altéré, même si l’altération ne produit rien d’autre qu’une absurdité, peut avoir des coûts réels.An altered message, even if the alteration results in nothing but nonsense, can have real costs. Un code d’authentification des messages (MAC) permet d’empêcher la falsification des messages.A message authentication code (MAC) helps prevent message tampering. Par exemple, considérez le scénario suivant :For example, consider the following scenario:

  • Bob et Alice partagent une clé secrète et conviennent d’une fonction MAC à utiliser.Bob and Alice share a secret key and agree on a MAC function to use.
  • Bob crée un message, puis entre le message et la clé secrète dans une fonction MAC pour récupérer une valeur MAC.Bob creates a message and inputs the message and the secret key into a MAC function to retrieve a MAC value.
  • Bob envoie le [ message non chiffré ] et la valeur Mac à Alice sur un réseau.Bob sends the [unencrypted] message and the MAC value to Alice over a network.
  • Alice utilise la clé secrète et le message comme entrée pour la fonction MAC.Alice uses the secret key and the message as input to the MAC function. Elle compare la valeur MAC générée à la valeur MAC envoyée par Bob.She compares the generated MAC value to the MAC value sent by Bob. Si elles sont identiques, cela indique que le message n’a pas été modifié lors du transit.If they are the same, the message was not changed in transit.

Notez qu’Eve, une tierce personne effectuant une écoute clandestine de la conversation entre Bob et Alice, ne peut effectivement pas manipuler le message.Note that Eve, a third party eavesdropping on the conversation between Bob and Alice, cannot effectively manipulate the message. Eve n’a pas accès à la clé privée et, par conséquent, ne peut pas créer de valeur MAC qui ferait apparaître le message falsifié comme légitime à Alice.Eve does not have access to the private key and cannot, therefore, create a MAC value which would make the tampered message appear legitimate to Alice.

La création d’un code d’authentification des messages garantit que le message d’origine n’a pas été altéré et, en utilisant une clé secrète partagée, que le hachage du message a été signé par une personne ayant accès à cette clé privée.Creating a message authentication code ensures only that the original message was not altered and, by using a shared secret key, that the message hash was signed by someone with access to that private key.

Vous pouvez utiliser MacAlgorithmProvider pour énumérer les algorithmes Mac disponibles et générer une clé symétrique.You can use the MacAlgorithmProvider to enumerate the available MAC algorithms and generate a symmetric key. Vous pouvez utiliser des méthodes statiques sur la classe CryptographicEngine pour effectuer le chiffrement nécessaire qui crée la valeur Mac.You can use static methods on the CryptographicEngine class to perform the necessary encryption that creates the MAC value.

Les signatures numériques sont l’équivalent, pour les clés publiques, des codes d’authentification de message (MAC) des clés privées.Digital signatures are the public key equivalent of private key message authentication codes (MACs). Bien que les codes d’authentification des messages (MAC, Message Authentication Codes) utilisent des clés privées pour permettre au destinataire d’un message de vérifier qu’un message n’a pas été altéré pendant la transmission, les signatures utilisent une paire clé privée/clé publique.Although MACs use private keys to enable a message recipient to verify that a message has not been altered during transmission, signatures use a private/public key pair.

Cet exemple de code montre comment utiliser la classe MacAlgorithmProvider pour créer un code d’authentification de message haché (HMAC).This example code shows how to use the MacAlgorithmProvider class to create a hashed message authentication code (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 hachageHashes

Une fonction de hachage de chiffrement prend un long bloc de données au hasard et renvoie une chaîne de bits de taille fixe.A cryptographic hash function takes an arbitrarily long block of data and returns a fixed-size bit string. Les fonctions de hachage sont généralement utilisées dans le cadre de la signature de données.Hash functions are typically used when signing data. Comme la plupart des opérations de signature de clé publique sont gourmandes en calcul, il est plus efficace de signer (chiffrer) un hachage de message plutôt que le message d’origine.Because most public key signature operations are computationally intensive, it is typically more efficient to sign (encrypt) a message hash than it is to sign the original message. La procédure suivante représente un cas courant, bien que simplifié :The following procedure represents a common, albeit simplified, scenario:

  • Bob et Alice partagent une clé secrète et conviennent d’une fonction MAC à utiliser.Bob and Alice share a secret key and agree on a MAC function to use.
  • Bob crée un message, puis entre le message et la clé secrète dans une fonction MAC pour récupérer une valeur MAC.Bob creates a message and inputs the message and the secret key into a MAC function to retrieve a MAC value.
  • Bob envoie le [ message non chiffré ] et la valeur Mac à Alice sur un réseau.Bob sends the [unencrypted] message and the MAC value to Alice over a network.
  • Alice utilise la clé secrète et le message comme entrée pour la fonction MAC.Alice uses the secret key and the message as input to the MAC function. Elle compare la valeur MAC générée à la valeur MAC envoyée par Bob.She compares the generated MAC value to the MAC value sent by Bob. Si elles sont identiques, cela indique que le message n’a pas été modifié lors du transit.If they are the same, the message was not changed in transit.

Notez qu’Alice a envoyé un message non chiffré.Note that Alice sent an unencrypted message. Seul le hachage était chiffré.Only the hash was encrypted. La procédure permet uniquement de s’assurer que le message d’origine n’a pas été modifié et, à l’aide de la clé publique d’Alice, que le hachage du message a été signé par quelqu’un qui a accès à la clé privée d’Alice, probablement Alice elle-même.The procedure ensures only that the original message was not altered and, by using Alice's public key, that the message hash was signed by someone with access to Alice's private key, presumably Alice.

Vous pouvez utiliser la classe HashAlgorithmProvider pour énumérer les algorithmes de hachage disponibles et créer une valeur CryptographicHash.You can use the HashAlgorithmProvider class to enumerate the available hash algorithms and create a CryptographicHash value.

Les signatures numériques sont l’équivalent, pour les clés publiques, des codes d’authentification de message (MAC) des clés privées.Digital signatures are the public key equivalent of private key message authentication codes (MACs). Alors que les codes MAC utilisent des clés privées pour permettre au destinataire d’un message de vérifier que celui-ci n’a pas été modifié au cours de transmission, les signatures utilisent une paire de clés privée/publique.Whereas MACs use private keys to enable a message recipient to verify that a message has not been altered during transmission, signatures use a private/public key pair.

L’objet CryptographicHash peut être utilisé pour hacher plusieurs fois des données différentes sans avoir à recréer l’objet pour chaque utilisation.The CryptographicHash object can be used to repeatedly hash different data without having to re-create the object for each use. La méthode Append ajoute de nouvelles données à une mémoire tampon en vue d’être hachées.The Append method adds new data to a buffer to be hashed. La méthode GetValueAndReset hache les données et réinitialise l’objet pour une autre utilisation.The GetValueAndReset method hashes the data and resets the object for another use. En voici une illustration dans l’exemple suivant.This is shown by the following example.

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ériquesDigital signatures

Les signatures numériques sont l’équivalent, pour les clés publiques, des codes d’authentification de message (MAC) des clés privées.Digital signatures are the public key equivalent of private key message authentication codes (MACs). Alors que les codes MAC utilisent des clés privées pour permettre au destinataire d’un message de vérifier que celui-ci n’a pas été modifié au cours de transmission, les signatures utilisent une paire de clés privée/publique.Whereas MACs use private keys to enable a message recipient to verify that a message has not been altered during transmission, signatures use a private/public key pair.

Comme la plupart des opérations de signature de clé publique sont gourmandes en calcul, il est toutefois plus efficace de signer (chiffrer) un hachage de message plutôt que le message d’origine.Because most public key signature operations are computationally intensive, however, it is typically more efficient to sign (encrypt) a message hash than it is to sign the original message. L’expéditeur crée un hachage de message, le signe et envoie la signature et le message (non chiffré).The sender creates a message hash, signs it, and sends both the signature and the (unencrypted) message. Le destinataire calcule un hachage sur le message, déchiffre la signature et compare la signature déchiffrée à la valeur de hachage.The recipient calculates a hash over the message, decrypts the signature, and compares the decrypted signature to the hash value. Si elles correspondent, le destinataire peut être quasi certain que le message provient effectivement de l’expéditeur et qu’il n’a pas été modifié au cours de la transmission.If they match, the recipient can be fairly certain that the message did, in fact, come from the sender and was not altered during transmission.

La signature permet uniquement de s’assurer que le message d’origine n’a pas été modifié et, à l’aide de la clé publique de l’expéditeur, que le hachage du message a été signé par quelqu’un qui a accès à la clé privée.Signing ensures only that the original message was not altered and, by using the sender's public key, that the message hash was signed by someone with access to the private key.

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.You can use an AsymmetricKeyAlgorithmProvider object to enumerate the available signature algorithms and generate or import a key pair. Vous pouvez utiliser des méthodes statiques sur la classe CryptographicHash pour signer un message ou vérifier une signature.You can use static methods on the CryptographicHash class to sign a message or verify a signature.