Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A autenticação de mensagens é um processo que permite que aplicativos e provedores de serviços verifiquem se os dados passados entre eles não foram adulterados. O Gestor de Dispositivos do Windows Media permite que aplicações e fornecedores de serviços efetuem autenticação de mensagens utilizando códigos de autenticação de mensagens (MACs). Aqui está como a autenticação MAC funciona:
O remetente dos dados, geralmente o provedor de serviços, passa uma ou mais partes de dados através de uma função criptográfica unidirecional que produz uma única assinatura, o MAC, para todos os dados. Em seguida, o remetente envia todos os dados assinados juntamente com o MAC para o recetor (geralmente o aplicativo). O recetor passa os dados através da mesma função criptográfica para gerar um MAC e compara-o com o MAC que foi enviado. Se o MAC corresponder, os dados não foram modificados.
Para executar a autenticação MAC, o aplicativo ou provedor de serviços requer uma chave de criptografia e um certificado correspondente. Para obter informações sobre onde obtê-los, consulte Tools for Development.
As etapas a seguir descrevem como os dados são assinados pelo remetente e, posteriormente, verificados pelo destinatário. No Gerenciador de dispositivos do Windows Media, o provedor de serviços usa a classe CSecureChannelServer para gerar MACs e o aplicativo usa a classe CSecureChannelClient. Ambas as classes fornecem funções idênticas com parâmetros idênticos, portanto, as etapas a seguir se aplicam a ambas as classes.
O remetente (normalmente o provedor de serviços):
- Obtenha os dados a serem assinados.
- Crie um novo identificador MAC chamando MACInit.
- Adicione uma parte dos dados a serem assinados ao identificador chamando MACUpdate. Esta função aceita o identificador criado anteriormente, além de uma parte dos dados que devem ser assinados.
- Repita a etapa 3 com cada dado adicional que deve ser assinado. Não importa em que ordem os dados são adicionados ao MAC.
- Copie o MAC do identificador para um novo buffer de bytes chamando MACFinal. Esta função aceita o identificador MAC e um buffer que você alocar e copia o MAC do identificador para o buffer fornecido.
Ao executar a autenticação MAC, é importante que tanto o emissor eo recetor estão colocando os mesmos dados no MAC. Para os métodos de aplicação que fornecem um MAC, normalmente todos os parâmetros são incluídos no valor MAC (exceto o próprio MAC, é claro). Por exemplo, considere o IWMDMOperation::TransferObjectData método:
HRESULT TransferObjectData(BYTE* pData, DWORD* pdwSize, BYTE[WMDM_MAC_LENGTH] abMac);
Neste método, o MAC incluiria pData e pdwSize. Se você não incluir ambos os parâmetros, o MAC que você criar não corresponderá ao MAC passado para abMac. Um provedor de serviços deve ter certeza de colocar todos os parâmetros necessários no método de aplicação no valor MAC.
O código C++ a seguir demonstra a criação de um MAC na implementação de um provedor de serviços de 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;
}
O recetor (normalmente a aplicação):
Se o recetor não implementou o IWMDMOperation3 interface, ele deve executar as mesmas etapas que o remetente e, em seguida, comparar os dois valores MAC. O exemplo de código C++ a seguir mostra como um aplicativo verificaria o MAC recebido em uma chamada para IWMDMStorageGlobals::GetSerialNumber para garantir que o número de série não foi adulterado em trânsito.
//
// 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.
}
}
Tópicos relacionados