Windows 25H2及后续版本中ECDH_P256设置BCryptSetProperty HKDF为SHA256失败
问题描述
在使用Windows CryptNG(CNG)生成Diffie-Hellman密钥时,调用BCryptSetProperty设置HKDF的哈希算法为SHA256:
BCryptSetProperty(..., BCRYPT_HKDF_HASH_ALGORITHM, BCRYPT_SHA256_ALGORITHM, ...);
出现以下异常:
- 当算法标识符为
BCRYPT_DH_ALGORITHM("DH")时调用成功 - 当算法标识符为
BCRYPT_ECDH_P256_ALGORITHM("ECDH_P256")时调用失败,返回STATUS_INVALID_HANDLE错误码
该代码在Windows 11 22H2(22621.963)版本正常运行,但在Windows 11 25H2(26200.6584)及Windows 10 22H2(10.0.28000.1516)版本中失效。
问题复现代码
NTSTATUS GenDHKey(_Out_ BCRYPT_KEY_HANDLE *phKey, _In_ PCWSTR pszAlgId) { NTSTATUS status; BCRYPT_ALG_HANDLE hAlgorithm; if (0 <= (status = BCryptOpenAlgorithmProvider(&hAlgorithm, pszAlgId, 0, 0))) { BCRYPT_KEY_HANDLE hKey; status = BCryptGenerateKeyPair(hAlgorithm, &hKey, 0, 0); BCryptCloseAlgorithmProvider(hAlgorithm, 0); if (0 <= status) { if (0 > (status = BCryptFinalizeKeyPair(hKey, 0))) { BCryptDestroyKey(hKey); } else { *phKey = hKey; } } } return status; } NTSTATUS bug_demo(_In_ PCWSTR pszAlgId) { BCRYPT_KEY_HANDLE hKey; NTSTATUS status; if (0 <= (status = GenDHKey(&hKey, pszAlgId))) { BCRYPT_SECRET_HANDLE hSecret; status = BCryptSecretAgreement(hKey, hKey, &hSecret, 0); BCryptDestroyKey(hKey); if (0 <= status) { status = BCryptSetProperty(hSecret, BCRYPT_HKDF_HASH_ALGORITHM, (PBYTE)BCRYPT_SHA256_ALGORITHM, sizeof(BCRYPT_SHA256_ALGORITHM), 0); BCryptDestroySecret(hSecret); } } return status; } // 调用示例 bug_demo(BCRYPT_DH_ALGORITHM); bug_demo(BCRYPT_ECDH_P256_ALGORITHM);
问题原因
这个问题的核心是Windows CNG在新版本中对ECDH密钥协商生成的secret句柄的生命周期管理逻辑发生了变更:
- 旧版本行为:在Windows 11 22H2及更早版本中,
BCryptSecretAgreement生成的BCRYPT_SECRET_HANDLE不依赖于原密钥句柄,即使调用BCryptDestroyKey(hKey)销毁密钥,secret句柄仍保持有效,可正常执行BCryptSetProperty。 - 新版本行为:在Windows 11 25H2和Windows 10 22H2的后续更新中,CNG调整了ECDH的依赖规则——ECDH的secret句柄会绑定到生成它的密钥句柄。当密钥句柄被销毁后,对应的ECDH secret句柄会被隐式标记为无效,此时调用
BCryptSetProperty就会返回STATUS_INVALID_HANDLE错误。而传统DH算法的secret句柄未受此变更影响,仍可在密钥销毁后正常操作。 - 验证方法:将
BCryptDestroyKey(hKey)的调用移到BCryptSetProperty之后,ECDH场景下的属性设置操作即可正常执行。
内容的提问来源于stack exchange,提问作者RbMm
相关产品推荐
相关产品推荐

