Проверка подлинности сообщений
Проверка подлинности сообщений — это процесс, который позволяет приложениям и поставщикам служб проверять, что данные, передаваемые между ними, не были изменены. Windows Media диспетчер устройств позволяет приложениям и поставщикам служб выполнять проверку подлинности сообщений с помощью кодов проверки подлинности сообщений (MAC). Вот как работает проверка подлинности MAC:
Отправитель данных, как правило, поставщик услуг, передает один или несколько фрагментов данных с помощью односторонняя криптографическая функция, которая создает для всех данных одну сигнатуру MAC. Затем отправитель отправляет все подписанные фрагменты данных вместе с MAC получателю (обычно это приложение). Получатель передает данные через ту же криптографическую функцию для создания MAC-адреса и сравнивает их с отправленным mac-адресом. Если MAC-адрес совпадает, данные не были изменены.
Чтобы выполнить проверку подлинности MAC, приложению или поставщику услуг требуется ключ шифрования и соответствующий сертификат. Сведения о том, где их можно получить, см. в разделе Средства для разработки.
Ниже описано, как данные подписываются отправителем, а затем проверяются получателем. В Windows Media диспетчер устройств поставщик услуг использует класс CSecureChannelServer для создания mac, а приложение использует класс CSecureChannelClient. Оба класса предоставляют идентичные функции с одинаковыми параметрами, поэтому следующие действия применимы к обоим классам.
Отправитель (обычно поставщик услуг):
- Получение подписываемого данных.
- Создайте новый дескриптор MAC, вызвав MACInit.
- Добавьте часть данных для подписи в дескриптор, вызвав MACUpdate. Эта функция принимает ранее созданный дескриптор, а также часть данных, которые должны быть подписаны.
- Повторите шаг 3 с каждым дополнительным фрагментом данных, который необходимо подписать. Не имеет значения, в каком порядке данные добавляются в MAC.
- Скопируйте MAC-адрес из дескриптора в новый буфер байтов, вызвав MACFinal. Эта функция принимает дескриптор MAC и выделенный буфер и копирует MAC-адрес из дескриптора в указанный буфер.
При выполнении проверки подлинности MAC важно, чтобы и отправитель, и получатель помещают одни и те же данные в MAC-адрес. Для методов приложения, предоставляющих MAC, обычно все параметры включаются в значение MAC (за исключением самого MAC, конечно). Например, рассмотрим метод IWMDMOperation::TransferObjectData :
HRESULT TransferObjectData(BYTE* pData, DWORD* pdwSize, BYTE[WMDM_MAC_LENGTH] abMac);
В этом методе MAC-адрес будет включать pData и pdwSize. Если не включить оба параметра, создаваемый MAC-адрес не будет соответствовать mac-адресу, переданном в abMac. Поставщик услуг должен обязательно поместить все необходимые параметры в методе приложения в значение MAC.
В следующем коде C++ показано создание MAC-адреса в реализации поставщика услуг 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;
}
Получатель (обычно это приложение):
Если получатель не реализовал интерфейс IWMDMOperation3 , он должен выполнить те же действия, что и отправитель, а затем сравнить два значения MAC. В следующем примере кода C++ показано, как приложение проверка mac-адреса, полученного в вызове IWMDMStorageGlobals::GetSerialNumber, чтобы убедиться, что серийный номер не был изменен при передаче.
//
// 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.
}
}
Связанные темы
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по