Condividi tramite


Autenticazione dei messaggi

L'autenticazione dei messaggi è un processo che consente alle applicazioni e ai provider di servizi di verificare che i dati passati tra di essi non siano stati manomessi. Windows Media Gestione dispositivi consente alle applicazioni e ai provider di servizi di eseguire l'autenticazione dei messaggi usando i codici di autenticazione dei messaggi . Ecco come funziona l'autenticazione MAC:

Il mittente dei dati, in genere il provider di servizi, passa una o più parti di dati tramite una funzione di crittografia unidirezionale che produce una singola firma, il MAC, per tutti i dati. Il mittente invia quindi tutti i dati firmati insieme al MAC al ricevitore (in genere l'applicazione). Il ricevitore passa i dati tramite la stessa funzione crittografica per generare un MAC e lo confronta con il MAC inviato. Se il MAC corrisponde, i dati non sono stati modificati.

Per eseguire l'autenticazione MAC, l'applicazione o il provider di servizi richiede una chiave di crittografia e un certificato corrispondente. Per informazioni su dove ottenere queste informazioni, vedere Strumenti per lo sviluppo.

I passaggi seguenti descrivono come i dati vengono firmati dal mittente e successivamente controllati dal ricevitore. In Windows Media Gestione dispositivi, il provider di servizi usa la classe CSecureChannelServer per generare i controller di rete e l'applicazione usa la classe CSecureChannelClient. Entrambe le classi forniscono funzioni identiche con parametri identici, quindi i passaggi seguenti si applicano a entrambe le classi.

Mittente (in genere il provider di servizi):

  1. Ottenere i dati da firmare.
  2. Creare un nuovo handle MAC chiamando MACInit.
  3. Aggiungere una parte di dati da firmare all'handle chiamando MACUpdate. Questa funzione accetta l'handle creato in precedenza, oltre a una parte di dati che deve essere firmata.
  4. Ripetere il passaggio 3 con ogni parte aggiuntiva di dati che deve essere firmata. Non importa in quale ordine vengono aggiunti i dati al MAC.
  5. Copiare il MAC dall'handle in un nuovo buffer di byte chiamando MACFinal. Questa funzione accetta l'handle MAC e un buffer allocato e copia il MAC dall'handle nel buffer fornito.

Quando si esegue l'autenticazione MAC, è importante che il mittente e il ricevitore inseriscano gli stessi dati nel MAC. Per i metodi dell'applicazione che forniscono un MAC, in genere tutti i parametri sono inclusi nel valore MAC (ad eccezione del MAC stesso, naturalmente). Si consideri ad esempio il metodo IWMDMOperation::TransferObjectData :

HRESULT TransferObjectData(BYTE* pData, DWORD* pdwSize, BYTE[WMDM_MAC_LENGTH] abMac);

In questo metodo, il MAC includerebbe pData e pdwSize. Se non si includono entrambi i parametri, il MAC creato non corrisponderà al MAC passato a abMac. Un provider di servizi deve essere sicuro di inserire tutti i parametri necessari nel metodo applicazione nel valore MAC.

Il codice C++ seguente illustra la creazione di un MAC nell'implementazione di IMDSPStorageGlobals::GetSerialNumber.

HRESULT CMyDevice::GetSerialNumber(
    PWMDMID pSerialNumber, 
    BYTE abMac[WMDM_MAC_LENGTH])
{
    HRESULT hr;

    // g_pSecureChannelServer is a global CSecureChannelServer object
    // created earlier.

    // Standard check that the CSecureChannelServer was authenticated previously.
    if ( !(g_pSecureChannelServer->fIsAuthenticated()) )
    {
        return WMDM_E_NOTCERTIFIED;
    }

    // Call a helper function to get the device serial number.
    hr = UtilGetSerialNumber(m_wcsName, pSerialNumber, TRUE);
    if(hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED))
    {
        hr = WMDM_E_NOTSUPPORTED;
    }

    if(hr == S_OK)
    {
        // Create the MAC handle.
        HMAC hMAC;
        hr = g_pSecureChannelServer->MACInit(&hMAC);
        if(FAILED(hr))
            return hr;

        // Add the serial number to the MAC.
        g_pSecureChannelServer->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID));
        if(FAILED(hr))
            return hr;

        // Get the created MAC value from the handle.
        g_pSecureChannelServer->MACFinal(hMAC, abMac);
        if(FAILED(hr))
            return hr;
    }

    return hr;
}

Ricevitore (in genere l'applicazione):

Se il ricevitore non ha implementato l'interfaccia IWMDMOperation3 , deve eseguire gli stessi passaggi del mittente e quindi confrontare i due valori MAC. Nell'esempio di codice C++ seguente viene illustrato come un'applicazione controlla il MAC ricevuto in una chiamata a IWMDMStorageGlobals::GetSerialNumber per assicurarsi che il numero di serie non sia stato manomesso in transito.

//
// Get and verify the serial number.
//
WMDMID serialNumber;
BYTE receivedMAC[WMDM_MAC_LENGTH];
hr = pIWMDMDevice->GetSerialNumber(&serialNumber, receivedMAC);

// Check the MAC to guarantee the serial number has not been tampered with.
if (hr == S_OK)
{
    // Initialize a MAC handle, 
    // add all parameters to the MAC,
    // and retrieve the calculated MAC value.
    // m_pSAC is a global CSecureChannelClient object created earlier.
    HMAC hMAC;
    BYTE calculatedMAC[WMDM_MAC_LENGTH];
    hr = m_pSAC->MACInit(&hMAC);
    if(FAILED(hr))
        return hr;

    hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(&serialNumber), sizeof(serialNumber));
    if(FAILED(hr))
        return hr;

    hr = m_pSAC->MACFinal(hMAC, (BYTE*)calculatedMAC);
    if(FAILED(hr))
        return hr;

    // If the two MAC values match, the MAC is authentic. 
    if (memcmp(calculatedMAC, receivedMAC, sizeof(calculatedMAC)) == 0)
    {
        // The MAC is authentic; print the serial number.
        CHAR* serialNumberBuffer = 
            new CHAR[serialNumber.SerialNumberLength + 1];
        ZeroMemory(serialNumberBuffer, 
            (serialNumber.SerialNumberLength + 1) * sizeof(CHAR));
        memcpy(serialNumberBuffer, serialNumber.pID, 
            serialNumber.SerialNumberLength * sizeof(CHAR));
        // TODO: Display the serial number.
        delete serialNumberBuffer;
    }
    else
    {
        // TODO: Display a message indicating that the serial number MAC 
        // does not match.
    }
}

Uso di canali autenticati sicuri