暗号化と暗号化解除
Windows Media デバイス マネージャーでは、サービス プロバイダーとアプリケーションの間で送信されるファイルの暗号化が必要です。 これには、次の 2 とおりの方法があります。
- サービス プロバイダーが IMDSPObject::Read および IMDSPObject::Write のみをサポートしている場合は、CSecureChannelClient メソッドと CSecureChannelServer メソッドをそれぞれ使用して、アプリケーションとサービス プロバイダーによってデータを暗号化および暗号化解除する必要があります。
- サービス プロバイダーが IMDSPObject2::ReadOnClearChannel と IMDSPObject2::WriteOnClearChannel をサポートしている場合、アプリケーションはコストのかかるセキュリティで保護されたチャネル メッセージ認証を回避できます。 (セキュリティで保護されたチャネルは保持されるため、 IMDSPObject2 を実装していないレガシ サービス プロバイダーは引き続き機能できます)。
暗号化要件は、悪意のあるアプリケーションがソフトウェア コンポーネント間で渡されるデータを取得するのを防ぎ、デバイスとの間で送信されるデータの整合性も保護します。
次の 3 つの方法では、暗号化または暗号化解除が必要です。
メソッド | 説明 |
---|---|
IWMDMOperation::TransferObjectData | (アプリケーション)アプリケーションがデータを送受信しているかどうかに応じて、暗号化または暗号化解除を行います。 |
IMDSPObject::Read | (サービス プロバイダー)暗号化。 |
IMDSPObject::Write | (サービス プロバイダー)復 号 化。 |
暗号化と暗号化解除は、どちらも単一のメソッド呼び出しによって行われます。 暗号化は、アプリケーションの 場合は CSecureChannelClient::EncryptParam 、サービス プロバイダーの 場合は CSecureChannelServer::EncryptParam によって行われます。 復号化は、アプリケーションの 場合は CSecureChannelClient::D ecryptParam 、サービス プロバイダーの 場合は CSecureChannelServer::D ecryptParam によって行われます。 パラメーターは、クライアント メソッドとサーバー メソッドの間で同じです。
次の手順では、データの暗号化と暗号化解除を行う方法を示します。 (これらの手順は、アプリケーションが IWMDMOperation3::TransferObjectDataOnClearChannel を実装していないレガシ サービス プロバイダーと通信する場合にのみ重要です)。
暗号化
- 「メッセージ認証」で説明されているように、暗号化されたデータの MAC キーを作成します。
- 暗号化するデータを使用して EncryptParam を呼び出して、インプレース暗号化を実行します。
次のコード例は、 IMDSPObject::Read のサービス プロバイダーの実装を示しています。 このメソッドは、暗号化するデータとデータのサイズを使用して MAC キーを作成し、両方をアプリケーションに送信します。
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;
}
暗号化の解除
- 暗号化するデータを使用して DecryptParam を呼び出して、インプレース復号化を実行します。
- 「メッセージ認証」の説明に従って、復号化されたデータの MAC キーを確認します。
次のコード例は、サービス プロバイダーによる IMDSPObject::Write の実装を示しています。 このメソッドは、暗号化するデータとデータのサイズを使用して MAC キーを作成し、両方をアプリケーションに送信します。
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;
}
関連トピック