Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra in che modo i codici di autenticazione dei messaggi ,gli hash e le firme possono essere usati nelle app WinUI per rilevare la manomissione dei messaggi.
Codici di autenticazione dei messaggi (MACS)
La crittografia consente a un utente non autorizzato di leggere un messaggio, ma non impedisce a tale individuo di manomettere il messaggio. Un messaggio modificato, anche se l'alterazione non comporta alcuna sciocchezza, può avere costi reali. Un codice MAC (Message Authentication Code) consente di evitare manomissioni dei messaggi. Ad esempio, si consideri il seguente scenario:
- Bob e Alice condividono una chiave privata e accettano una funzione MAC da usare.
- Bob crea un messaggio e inserisce il messaggio e la chiave privata in una funzione MAC per recuperare un valore MAC.
- Bob invia il messaggio [non crittografato] e il valore MAC ad Alice su una rete.
- Alice usa la chiave privata e il messaggio come input per la funzione MAC. Confronta il valore MAC generato con il valore MAC inviato da Bob. Se sono uguali, il messaggio non è stato modificato in transito.
Si noti che Eve, un'intercettatrice di terze parti che spia la conversazione tra Bob e Alice, non può manipolare efficacemente il messaggio. Eve non ha accesso alla chiave privata e non può quindi creare un valore MAC che renderebbe legittimo il messaggio manomesso ad Alice.
La creazione di un codice di autenticazione del messaggio garantisce solo che il messaggio originale non sia stato modificato e, usando una chiave privata condivisa, che l'hash del messaggio sia stato firmato da un utente con accesso a tale chiave privata.
È possibile usare MacAlgorithmProvider per enumerare gli algoritmi MAC disponibili e generare una chiave simmetrica. È possibile usare metodi statici nella classe CryptographicEngine per eseguire la crittografia necessaria che crea il valore MAC.
Le firme digitali sono l'equivalente della chiave pubblica dei codici di autenticazione dei messaggi di chiave privata. Anche se i mac usano chiavi private per consentire a un destinatario di messaggi di verificare che un messaggio non sia stato modificato durante la trasmissione, le firme usano una coppia di chiavi privata/pubblica.
Questo codice di esempio illustra come usare la classe MacAlgorithmProvider per creare un codice HMAC (Hashed Message Authentication Code).
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.");
}
}
}
}
Hashes
Una funzione hash crittografica accetta un blocco di dati arbitrariamente lungo e restituisce una stringa di bit a dimensione fissa. Le funzioni hash vengono in genere usate durante la firma dei dati. Poiché la maggior parte delle operazioni di firma della chiave pubblica richiede un utilizzo intensivo del calcolo, in genere è più efficiente firmare (crittografare) un hash dei messaggi rispetto a quello di firmare il messaggio originale. La procedura seguente rappresenta uno scenario comune, sebbene semplificato:
- Alice ha una coppia di chiavi pubblica/privata e vuole inviare un messaggio firmato a Bob.
- Alice crea un messaggio e calcola un hash del messaggio usando una funzione hash.
- Alice firma l'hash usando la chiave privata e invia il messaggio [non crittografato] e la firma a Bob su una rete.
- Bob calcola un hash del messaggio ricevuto usando la stessa funzione hash. Usa quindi la chiave pubblica di Alice per decrittografare la firma e la confronta con l'hash calcolato. Se sono uguali, il messaggio non è stato modificato in transito e proviene da Alice.
Si noti che Alice ha inviato un messaggio non crittografato. Solo l'hash è stato crittografato. La procedura garantisce solo che il messaggio originale non sia stato modificato e, usando la chiave pubblica di Alice, che l'hash del messaggio sia stato firmato da un utente con accesso alla chiave privata di Alice, presumibilmente Alice.
È possibile usare la classe HashAlgorithmProvider per enumerare gli algoritmi hash disponibili e creare un valore CryptographicHash .
Le firme digitali sono l'equivalente della chiave pubblica dei codici di autenticazione dei messaggi di chiave privata. Mentre i MAC usano chiavi private per consentire a un destinatario di messaggi di verificare che un messaggio non sia stato modificato durante la trasmissione, le firme usano una coppia di chiavi privata/pubblica.
L'oggetto CryptographicHash può essere usato per eseguire ripetutamente l'hashing di dati diversi senza dover ricreare l'oggetto per ogni utilizzo. Il metodo Append aggiunge nuovi dati a un buffer di cui eseguire l'hashing. Il metodo GetValueAndReset esegue l'hashing dei dati e reimposta l'oggetto per un altro utilizzo. Questo esempio è illustrato nell'esempio seguente.
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);
}
Firme digitali
Le firme digitali sono l'equivalente della chiave pubblica dei codici di autenticazione dei messaggi di chiave privata. Mentre i MAC usano chiavi private per consentire a un destinatario di messaggi di verificare che un messaggio non sia stato modificato durante la trasmissione, le firme usano una coppia di chiavi privata/pubblica.
Poiché la maggior parte delle operazioni di firma della chiave pubblica richiede un utilizzo intensivo del calcolo, tuttavia, è in genere più efficiente firmare (crittografare) un hash dei messaggi rispetto a quello di firmare il messaggio originale. Il mittente crea un hash del messaggio, lo firma e invia sia la firma che il messaggio (non crittografato). Il destinatario calcola un hash sul messaggio, decrittografa la firma e confronta la firma decrittografata con il valore hash. Se corrispondono, il destinatario può essere abbastanza certo che il messaggio sia stato effettivamente inviato dal mittente e non sia stato modificato durante la trasmissione.
La firma garantisce solo che il messaggio originale non sia stato modificato e, usando la chiave pubblica del mittente, che l'hash del messaggio sia stato firmato da un utente con accesso alla chiave privata.
È possibile utilizzare un oggetto AsymmetricKeyAlgorithmProvider per enumerare gli algoritmi di firma disponibili e generare o importare una coppia di chiavi. È possibile usare metodi statici nella classe CryptographicHash per firmare un messaggio o verificare una firma.