Win32加密API(Ncrypt/Bcrypt)简单修改后示例代码运行失败原因排查
各测试场景运行失败的根本原因
所有报错的核心触发来源为代码中调用NCryptSignHash接口时,将pPaddingInfo参数直接传入NULL,结合各加密算法的固有约束,分场景的具体原因如下:
1. SHA256 / DSA / 软件密钥存储提供程序 报NTE_INVALID_PARAMETER(0x80090027)
- 传统DSA算法(即代码使用的
BCRYPT_DSA_ALGORITHM)存在严格的密钥长度与哈希长度绑定规则:默认创建的1024位DSA密钥对,按照FIPS 186-3规范仅支持搭配长度20字节的SHA1哈希完成签名,原生不支持SHA256对应的32字节哈希输入。 - 代码调用
NCryptSignHash时传入的pPaddingInfo为NULL,系统无法识别需要适配的哈希算法匹配规则,直接判定参数无效返回。 - 补充说明:即使将DSA密钥长度提升到2048/3072位以支持SHA256,也必须通过
pPaddingInfo传入NCRYPT_DSA_PADDING_INFO结构明确指定对应哈希算法,无法依赖默认运行行为完成签名。
2. SHA1 / DSA / 平台加密提供程序 报NTE_NOT_SUPPORTED(0x80090029)
- 平台加密提供程序(
MS_PLATFORM_CRYPTO_PROVIDER)的底层实现基于TPM硬件安全模块,从Windows 10开始,TPM标准已淘汰对传统DSA算法的原生支持,该提供程序未实现传统DSA密钥的创建接口,因此在NCryptCreatePersistedKey步骤直接返回不支持属于设计预期,不属于代码逻辑异常。
3. SHA1 / RSA、SHA256 / RSA / 软件密钥存储提供程序 报NTE_INVALID_PARAMETER(0x80090027)
- RSA签名流程存在固有规则约束:根据填充方案的不同,RSA签名需要明确指定使用PKCS#1 v1.5填充、还是PSS填充,同时需要显式告知系统当前签名搭配的哈希算法类型。
- 由于代码中
NCryptSignHash的pPaddingInfo传入了NULL,系统无法确定具体的填充参数和哈希匹配规则,直接判定参数无效。 - 行为对比:ECDSA算法之所以在
pPaddingInfo传NULL时可以正常运行,是因为ECDSA为确定性签名流程,不存在填充方案的歧义,因此允许使用默认值,这和RSA、DSA的行为差异是算法设计本身决定的,不存在兼容性问题。
内容的提问来源于stack exchange,提问作者Captain'Flam
相关产品推荐
相关产品推荐

