Chiffrement et déchiffrement
Windows Media Gestionnaire de périphériques nécessite le chiffrement des fichiers envoyés entre le fournisseur de services et l’application. Cette opération peut être effectuée de deux manières :
- Si le fournisseur de services prend uniquement en charge IMDSPObject::Read et IMDSPObject::Write, les données doivent être chiffrées et déchiffrées par l’application et le fournisseur de services à l’aide des méthodes CSecureChannelClient et CSecureChannelServer respectivement.
- Si le fournisseur de services prend en charge IMDSPObject2::ReadOnClearChannel et IMDSPObject2::WriteOnClearChannel, votre application peut éviter une authentification de message de canal sécurisée coûteuse. (Le canal sécurisé est conservé afin que les fournisseurs de services hérités qui n’implémentent pas IMDSPObject2 puissent continuer à fonctionner.)
L’exigence de chiffrement empêche les applications malveillantes d’obtenir des données transmises entre les composants logiciels, et protège également l’intégrité des données envoyées vers ou depuis l’appareil.
Les trois méthodes suivantes nécessitent un chiffrement ou un déchiffrement.
Méthode | Description |
---|---|
IWMDMOperation::TransferObjectData | (Application) Chiffrement ou déchiffrement, selon que l’application envoie ou reçoit des données. |
IMDSPObject::Read | (Fournisseur de services) Cryptage. |
IMDSPObject::Write | (Fournisseur de services) Décryptage. |
Le chiffrement et le déchiffrement sont tous deux effectués par des appels de méthode unique. Le chiffrement est effectué par CSecureChannelClient::EncryptParam pour les applications ou par CSecureChannelServer::EncryptParam pour les fournisseurs de services. Le déchiffrement est effectué par CSecureChannelClient::D ecryptParam pour les applications ou par CSecureChannelServer::D ecryptParam pour les fournisseurs de services. Les paramètres sont identiques entre les méthodes client et serveur.
Les étapes suivantes montrent comment chiffrer et déchiffrer des données. (Ces étapes sont importantes uniquement si votre application communique avec un fournisseur de services hérité qui n’implémente pas IWMDMOperation3::TransferObjectDataOnClearChannel.)
Chiffrement
- Créez la clé MAC pour les données chiffrées, comme décrit dans Authentification de message.
- Appelez EncryptParam avec les données à chiffrer pour effectuer un chiffrement sur place.
L’exemple de code suivant illustre l’implémentation d’IMDSPObject::Read par un fournisseur de services. Cette méthode crée la clé MAC à l’aide des données à chiffrer et de la taille des données, puis les envoie à l’application.
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;
}
Déchiffrement
- Appelez DecryptParam avec les données à chiffrer, pour effectuer un déchiffrement sur place.
- Vérifiez la clé MAC pour les données déchiffrées, comme décrit dans Authentification des messages.
L’exemple de code suivant illustre l’implémentation d’IMDSPObject::Write par un fournisseur de services. Cette méthode crée la clé MAC à l’aide des données à chiffrer et de la taille des données, puis les envoie à l’application.
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;
}
Rubriques connexes