0

我一直在努力使用 Microsoft RPC 获得安全的 RPC 客户端/服务器。我没有使用COM,只是直接使用C。

我已经创建了一个根 CA 证书,并为服务器创建了一个由该证书签名的证书。证书安装到证书存储中。

RPC 可以在未加密的情况下正常工作,它甚至可以与 SCHANNEL 设置一起使用,只是未加密。

服务器代码:

RpcServerUseProtseqEpW(
    L"ncacn_ip_tcp", 
    RPC_C_LISTEN_MAX_CALLS_DEFAULT, 
    port, 
    NULL);

CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    (HCRYPTPROV)NULL,
    CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
    L"MY")

CertFindCertificateInStore(
    hStore,
    X509_ASN_ENCODING|PKCS_7_ASAN_ENCODING,
    CERT_FIND_SUBJEECT_STR,
    subject,
    NULL);

RpcCertGeneratePrincipalNameW(
    ccert_ctx_server, 
    RPC_C_FULL_CERT_CHAIN,
    serverPrincName);

schannel.dwVersion = SCHANNEL_CRED_VERSION;
schannel.cCreds = 1;
schannel.paCred = &ccert_ctx_server;

RpcServerRegisterAuthInfoW(
    serverPrincName,
    RPC_C_AUTHN_GSS_SCHANNEL,
    NULL,
    &schannel);

RpcServerRegisterIf2(
    h_v1_ifspec,
    NULL,
    NULL,
    RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH  // seems to be required by SCHANNEL
    RPC_C_LISTEN_MAX_CALLS_DEFAULT,
    (unsigned)-1,
    SecurityCallback);  SecurityCallback returns RPC_S_OK

客户代码:

RpcStringBindingComposeW(
    NULL,
    L"ncacn_ip_tcp",
    address,
    port,
    NULL,
    &stringBinding);

RpcBindingFronStringBindingW(
    stringBinding,
    hBind);

CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    (HCRYPTPROV)NULL,
    CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
    L"MY")

CertFindCertificateInStore(
    hStore,
    X509_ASN_ENCODING|PKCS_7_ASAN_ENCODING,
    CERT_FIND_SUBJEECT_STR,
    subject,
    NULL);

RpcCertGeneratePrincipalNameW(
    ccert_ctx_server, 
    RPC_C_FULL_CERT_CHAIN,
    serverPrincName);

schannel.dwVersion = SCHANNEL_CRED_VERSION;
schannel.cCreds = 1;
schannel.paCred = &ccert_ctx_client;

RpcServerRegisterAuthInfoW(
    serverPrincName,
    RPC_C_AUTHN_GSS_SCHANNEL,
    NULL,
    &schannel);

RpcBindingSetAuthInfo(
    hBind,
    serverPrincName,
    RPC_C_AUTHN_LEVEL_PKT_INTEGRITY,
    RPC_C_AUTHN_GSS_SCHANNEL,
    &schannelCred,
    RPC_C_AUTHZ_NONE)

鉴于所有这些 RPC 都可以工作,但它不会像使用wireshark 验证的那样被加密。我用一个非常小的 SCHANNEL 结构定义而不是使用 qos 结构来解决这个问题。没什么大不了的。唯一真正有所作为的是如果我将 RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH 更改为 RPC_IF_ALLOW_SECURE_ONLY。然后我在进行 RPC 调用时被拒绝访问。据我了解,这是 SCHANNEL 的正常功能,您必须在安全回调中提供自己的身份验证。

当我在安全回调中调用 RpcBindingInqAuthClient 时,我收到错误 1746:绑定不包含任何身份验证信息。

我浏览了 MSDN,一个分散在网络上的几个不同的链接,但是对于 SCHANNEL 的工作几乎没有什么帮助。

我对 SCHANNEL 的选择是我不能依赖 kerberos 或 ntlm。我在互联网上运行 tcp,所以证书对我有用。我不能使用 http,因为我不能在我的服务器上设置 IIS,DCE 的文档似乎比 schannel 还要少。

谢谢!

4

0 回答 0