我已经实现(Windows 10.0.17763.0/VS2017/C++)一个客户端/服务器应用程序,它使用 schannel 进行安全通信。现在的要求是仅使用一组密码套件来进行某些客户端和服务器之间的通信。
使用 BCryptAddContextFunction/BCryptRemoveContextFunction API,我可以更改 SChannel 中支持的密码,但这是系统范围的设置,不仅适用于我的应用程序。为了以编程方式控制它,我尝试在 AcquireCredentialsHandle 中使用 ALG_ID。以下是我的应用程序应该支持的唯一密码套件。
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
所以我构建了如下所示的 ALG_ID。
std::vector<ALG_ID> algos = { CALG_AES_256 , CALG_AES_128 , CALG_SHA_384 , CALG_SHA_256,CALG_ECDH_EPHEM,CALG_DH_EPHEM };
schannelCred.cSupportedAlgs = static_cast<DWORD>(algos.size());
schannelCred.palgSupportedAlgs = &algos[0];
使用wireshark我发现下面是我的应用程序使用上面的ALG_ID在客户端hello中提出的密码套件,
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
问题是,
- 我如何只允许AES_GCM批量加密?当我将 CALG_AES 添加到列表中时,AES_GCM和AES_CBC 都被允许。
- 我如何控制签名?添加 CALG_ECDH_EPHEM 启用了 TLS_ECDHE_ECDSA 和 TLS_ECDHE_RSA,我只需要 TLS_ECDHE_RSA。将 CALG_RSA_SIGN 添加到 ALG_ID 删除了 TLS_ECDHE_ECDSA 但它盯着允许 TLS_RSA_* 密码套件。