Freigeben über


Verschlüsselung und Entschlüsselung

Der Windows Media Device Manager erfordert eine Verschlüsselung von Dateien, die zwischen dem Dienstanbieter und der Anwendung gesendet werden. Dies kann auf eine von zwei Arten erfolgen:

Die Verschlüsselungsanforderung verhindert, dass böswillige Anwendungen Daten erhalten, die zwischen Softwarekomponenten übergeben werden, und schützt auch die Integrität der Daten, die an oder vom Gerät gesendet werden.

Die folgenden drei Methoden erfordern Verschlüsselung oder Entschlüsselung.

Methode Beschreibung
IWMDMOperation::TransferObjectData (Anwendung) Verschlüsselung oder Entschlüsselung, je nachdem, ob die Anwendung Daten sendet oder empfängt.
IMDSPObject::Read (Dienstanbieter) Verschlüsselung.
IMDSPObject::Write (Dienstanbieter) Entschlüsselung.

 

Verschlüsselung und Entschlüsselung erfolgen beide durch Aufrufe einzelner Methoden. Verschlüsselung erfolgt durch CSecureChannelClient::EncryptParam für Anwendungen oder durch CSecureChannelServer::EncryptParam für Dienstanbieter. Entschlüsselung erfolgt durch CSecureChannelClient::D ecryptParam für Anwendungen oder CSecureChannelServer::D ecryptParam für Dienstanbieter. Die Parameter sind identisch zwischen den Client- und Servermethoden.

Die folgenden Schritte zeigen, wie Daten verschlüsselt und entschlüsselt werden. (Diese Schritte sind nur wichtig, wenn Ihre Anwendung mit einem älteren Dienstanbieter kommuniziert, der nicht IWMDMOperation3::TransferObjectDataOnClearChannelimplementiert.)

Verschlüsselungs-

  1. Erstellen Sie den MAC-Schlüssel für die verschlüsselten Daten, wie in Nachrichtenauthentifizierungbeschrieben.
  2. Rufen Sie EncryptParam- mit den zu verschlüsselnden Daten auf, um eine direkte Verschlüsselung durchzuführen.

Das folgende Codebeispiel veranschaulicht die Implementierung von IMDSPObject::Readeines Dienstanbieters. Mit dieser Methode wird der MAC-Schlüssel mithilfe der Daten zum Verschlüsseln und der Größe der Daten erstellt und beide an die Anwendung gesendet.

HRESULT CMyStorage::Read(
    BYTE  *pData,
    DWORD *pdwSize,
    BYTE   abMac[WMDM_MAC_LENGTH])
{
    HRESULT  hr;
    DWORD    dwToRead;         // Bytes to read.
    DWORD    dwRead   = NULL;  // Bytes read.
    BYTE    *pTmpData = NULL;  // Temporary buffer to hold data before 
                               // it is copied to pData.

    // Use a global CSecureChannelServer member to verify that 
    // the client is authenticated.
    if (!(g_pAppSCServer->fIsAuthenticated()))
    {
        return WMDM_E_NOTCERTIFIED;
    }
    

    // Verify that the handle to the file to read is valid.
    if(m_hFile == INVALID_HANDLE_VALUE)
    {
        return E_FAIL;
    }

    // Create a buffer to hold the data read.    
    dwToRead = *pdwSize;
    pTmpData = new BYTE [dwToRead] ;
    if(!pTmpData)
        return E_OUTOFMEMORY;

    // Read data into the temporary buffer.
    if(ReadFile(m_hFile,(LPVOID)pTmpData,dwToRead,&dwRead,NULL)) 
    { 
        *pdwSize = dwRead; 

        if( dwRead )
        {
            // Create a MAC from all the parameters.
            // CORg is a macro that goes to Error label on failure.
            // MAC consists of data and size of data.
            HMAC hMAC;
            
            CORg(g_pAppSCServer->MACInit(&hMAC));
            CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), dwRead));
            CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(DWORD)));
            CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
            
            // Encrypt the data.
            CORg(g_pAppSCServer->EncryptParam(pTmpData, dwRead));
            
            // Copy data from the temporary buffer into the out parameter.
            memcpy(pData, pTmpData, dwRead);
        }
    
        hr = S_OK; 
    }
    else
    { 
        *pdwSize = 0; 

        hr = E_FAIL; 
    }

Error:

    if(pTmpData) 
    {
        delete [] pTmpData;
    }

    return hr;
} 

Entschlüsselung

  1. Rufen Sie DecryptParam- mit den zu verschlüsselnden Daten auf, um eine direkte Entschlüsselung durchzuführen.
  2. Überprüfen Sie den MAC-Schlüssel für die entschlüsselten Daten, wie in Nachrichtenauthentifizierungbeschrieben.

Das folgende Codebeispiel veranschaulicht die Implementierung von IMDSPObject::Writeeines Dienstanbieters. Mit dieser Methode wird der MAC-Schlüssel mithilfe der Daten zum Verschlüsseln und der Größe der Daten erstellt und beide an die Anwendung gesendet.

HRESULT CMyStorage::Write(BYTE *pData, DWORD *pdwSize,
                                 BYTE abMac[WMDM_MAC_LENGTH])
{
    HRESULT  hr;
    DWORD    dwWritten = 0;
    BYTE    *pTmpData  = NULL;          // Temporary buffer to hold the 
                                        // data during decryption.
    BYTE     pTempMac[WMDM_MAC_LENGTH]; // Temporary MAC that will be 
                                        // copied into the abMac
                                        // out parameter.

    if( m_hFile == INVALID_HANDLE_VALUE )
    {
        return E_FAIL;
    }

    // Allocate the temporary buffer and copy the encrypted data into it.
    pTmpData = new BYTE [*pdwSize];
    if(!pTmpData)
        return E_OUTOFMEMORY;
    memcpy(pTmpData, pData, *pdwSize);

    // Decrypt the data.
    CHRg(g_pAppSCServer->DecryptParam(pTmpData, *pdwSize));

    // Check the MAC passed to the method. The MAC is built from
    // the data and data size parameters.
    // CORg is a macro that goes to the Error label on failure.
    HMAC hMAC;
    CORg(g_pAppSCServer->MACInit(&hMAC));
    CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), *pdwSize));
    CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(*pdwSize)));
    CORg(g_pAppSCServer->MACFinal(hMAC, pTempMac));

    // If the MAC values don't match, return an error.
    if (memcmp(abMac, pTempMac, WMDM_MAC_LENGTH) != 0)
    {
        hr = WMDM_E_MAC_CHECK_FAILED;
        goto Error;
    }

    // The MAC values matched, so write the decrypted data to a local file.
    if( WriteFile(m_hFile,pTmpData,*pdwSize,&dwWritten,NULL) ) 
    {
        hr = S_OK;
    }
    else 
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }

    *pdwSize = dwWritten;

Error:

    if( pTmpData )
    {
        delete [] pTmpData;
    }

    return hr;
}

Verwenden von sicher authentifizierten Kanälen