我有一个进程外的COM服务器暴露了一个我不希望被我不信任的代码调用的方法。
基本上我要做的就是阻止聪明的客户调用这些我需要访问的方法。我认为应该考虑一个不同的解决方案。但由于我不愿意进入的原因,我没有真正的选择。我可以采用不太强大的解决方案,但更愿意尽可能强大。
我可以更改客户端和服务器代码。服务器是用C ++编写的,客户端是用C#编写的。
保护这些电话的最佳方式是什么?
我认为这样的问题对于进程间通信或远程过程调用来说并不罕见。所以我希望有一个可接受的行业最佳实践,或者甚至是一个直接的COM解决方案。在没有这样的情况下,我倾向于从参数中抓取下划线数据,并使用该数据的片段作为字符串,使用来自另一部分数据的密钥进行加密,并将其传递给要验证的服务器。
答案 0 :(得分:0)
如果有一个开箱即用的COM解决方案,或者最佳实践,我没有找到任何解决方案。我发现的一种常见技术是使用哈希键。客户端生成密钥并将其传递给服务器。服务器生成相同的密钥,如果它与客户端密钥不匹配,则拒绝该呼叫。
我的哈希密钥基于从API正在处理的基础数据中提取的一些秘密。由于我的数据因每次使用而异,因此密钥每次都不同。双方都可以在呼叫之前访问基础数据,这样他们就可以生成相同的密钥。我选择base64编码我的,只是因为我更喜欢将一个NULL终止字符数组而不是字节数组传递给服务器。
LPCSTR lpszSomeSecret = "Some Secret To Be Hashed" ;
std::string strEncodedHash ; // the resulting hash.
HCRYPTPROV hProv = NULL ;
HCRYPTHASH hHash = NULL ;
DWORD cbSomeSecret = (DWORD)::strlen(lpszSomeSecret) ;
BYTE* pbHash = NULL ;
DWORD cbHash = 0 ;
DWORD cbHashSize = (DWORD)sizeof(cbHash) ;
LPSTR pchEncodedHash = NULL ;
int cbEncodedHash = 0 ;
HRESULT hResult = S_OK ;
if (!::CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
hResult = ::AtlHresultFromLastError() ;
} else if (!::CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
hResult = ::AtlHresultFromLastError() ;
} else if (!::CryptHashData(hHash, (BYTE*)lpszSomeSecret, cbSomeSecret, 0)) {
hResult = ::AtlHresultFromLastError() ;
} else if (!::CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHash, &cbHashSize, 0)) {
hResult = ::AtlHresultFromLastError() ;
} else if ((pbHash = (BYTE*)::malloc(cbHash)) == NULL) {
hResult = E_OUTOFMEMORY ;
} else if (!::CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0)) {
hResult = ::AtlHresultFromLastError() ;
} else if ((pchEncodedHash = (LPSTR)::malloc(
(cbEncodedHash = ::Base64EncodeGetRequiredLength(cbHash, ATL_BASE64_FLAG_NOPAD | ATL_BASE64_FLAG_NOCRLF))
)) == NULL) {
hResult = E_OUTOFMEMORY ;
} else if (!::Base64Encode(pbHash, cbHash, pchEncodedHash, &cbEncodedHash, ATL_BASE64_FLAG_NOPAD | ATL_BASE64_FLAG_NOCRLF)) {
hResult = E_FAIL ;
} else {
strEncodedHash.assign(pchEncodedHash, cbEncodedHash) ;
}
if (pchEncodedHash) ::free(pchEncodedHash) ;
if (pbHash) ::free(pbHash) ;
if (hProv) ::CryptReleaseContext(hProv, 0) ;
if (hHash) ::CryptDestroyHash(hHash) ;