确定 Schannel 连接的属性 -> returns 未知值

Determine attributes of an Schannel connection -> returns unknown value

成功Creating a Secure Connection Using Schannel, I am obtaining its connection attributes using QueryContextAttributes()后,通过SECPKG_ATTR_CONNECTION_INFO.

返回的结构 SecPkgContext_ConnectionInfo 包含字段 aiExch,其中包含我要查找的信息 - 即使用的密钥交换算法。

我已经使用它几个月了,它总是返回两个预定义值之一 CALG_RSA_KEYXCALG_DH_EPHEM. 但是自从几个星期以来(当我相信 Schannel 更新补丁是由Microsoft) 它 returns 一个未知值:0x0000ae06

使用这些宏,ALG_ID 可以拆分成它的组件:

#define GET_ALG_CLASS(x)                (x & (7 << 13))
#define GET_ALG_TYPE(x)                 (x & (15 << 9))
#define GET_ALG_SID(x)                  (x & (511))

据此,0x0000ae06 表示:

Class: ALG_CLASS_KEY_EXCHANGE
输入:(7 << 9) -> 未定义
SID: 6 -> 其含义取决于算法类型

有人 运行 遇到同样的问题吗?谁能解释一下发生了什么,或者 0x0000ae06 代表什么?

查看此处找到的代码 http://pastebin.com/TKQJ85Z9 请注意,ID 已添加到 schannel 库中,但显然 VC headers 无论如何都没有更新,从上面的代码可以看出(见pastebin URL),那个ID对应的是"ECDHE",也就是Elliptic Curve DH with Ephemeral key exchange

[编辑]

真正的问题是该值是非官方的,只能通过某些互联网搜索找到,这就是为什么我将 link 发布到一些示例代码;看,我刚好通过看这个推文找到了答案https://twitter.com/ericlaw/status/301083494203928576

无论如何,听起来最新版本的 Microsoft CNG SDK 包含更新的 headers 和为“QueryContextAttributes”添加新常量的库API调用,也就是SECPKG_ATTR_CIPHER_INFO这样调用returns一个结构体(见下面代码中的定义)其成员名为“szCipherSuite ”报告正在使用的密码的完整字符串,例如“TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384

下面是此类调用的一些示例代码

/*
// -- http://www.microsoft.com/en-us/download/details.aspx?id=1251
typedef struct _SecPkgContext_CipherInfo
{

    DWORD dwVersion;
    DWORD dwProtocol;
    DWORD dwCipherSuite;
    DWORD dwBaseCipherSuite;
    WCHAR szCipherSuite[SZ_ALG_MAX_SIZE];
    WCHAR szCipher[SZ_ALG_MAX_SIZE];
    DWORD dwCipherLen;
    DWORD dwCipherBlockLen;    // in bytes
    WCHAR szHash[SZ_ALG_MAX_SIZE];
    DWORD dwHashLen;
    WCHAR szExchange[SZ_ALG_MAX_SIZE];
    DWORD dwMinExchangeLen;
    DWORD dwMaxExchangeLen;
    WCHAR szCertificate[SZ_ALG_MAX_SIZE];
    DWORD dwKeyType;
} SecPkgContext_CipherInfo, *PSecPkgContext_CipherInfo;
*/    

static void DisplayConnectionInfo(CtxtHandle *phContext)
{
  SECURITY_STATUS Status;
  SecPkgContext_CipherInfo CipherInfo = { SECPKGCONTEXT_CIPHERINFO_V1 };

  Status = QueryContextAttributes( phContext, SECPKG_ATTR_CIPHER_INFO, &CipherInfo);    
  if(Status != SEC_E_OK) 
  { 
    printf("Error 0x%x querying cipher info\n", Status); 
    return; 
  }

  printf("%S\n", CipherInfo.szCipherSuite);
}

有关更多信息,请获取 MS CNG SDK 并查看包含的帮助和 headers。