CryptoAPI RSA Schannel 提供程序错误

标签 c rsa provider cryptoapi schannel

我正在尝试使用“Microsoft RSA SChannel Cryptographic Provider”生成数字签名。获取容器句柄后,我使用 CryptGenKey() 生成签名。但这个函数返回FALSE。

CryptGenKey() 的 dwError 返回 80090008。

这同样适用于任何其他提供商类型。另外,当我尝试为同一提供商创建 key 交换对时,它工作正常。我做错了什么?

#include <Windows.h>
#include <wincrypt.h>

int main()
{
    HCRYPTPROV phProv = 0;
    LPTSTR pszContainer = NULL;
    DWORD dwFlags = 0;
    bool flag;
    DWORD_PTR dwError;
    HCRYPTKEY phKey;

    flag = CryptAcquireContext(&phProv, pszContainer,
        MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, dwFlags);
    if (!flag)
    {
        flag = CryptAcquireContext(&phProv, pszContainer,
            MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_NEWKEYSET);
    }
    dwError = GetLastError();

    flag = CryptGenKey(phProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &phKey);
    dwError = GetLastError();

    flag = CryptGetUserKey(phProv, AT_SIGNATURE, &phKey);
    dwError = GetLastError();

    return 0;
}

谢谢。

最佳答案

SChannel 提供商不支持 AT_SIGNATURE RSA key ,仅支持 AT_EXCHANGE。这主要是早期 TLS(当时还是 SSL)的延续,当时使用 RSA 加密交换 key ,而不是使用通过 RSA 签名签署的 Diffie-Hellman key 协议(protocol)达成一致……然后,大概“好吧,每个人都知道如何SChannel 提供商的行为如此,为什么要改变它?”。 (我看到最接近的记录是 https://msdn.microsoft.com/en-us/library/windows/desktop/aa387690(v=vs.85).aspx ,它显示 CALG_RSA_KEYX 并且不谈论 CALG_RSA_SIGN。)

在 CAPI 中,AT_EXCHANGE key 可以同时进行加密和签名,而 AT_SIGNATURE key 只能进行签名。

总的来说,Windows 密码学团队不鼓励使用 CAPI 编写新代码(除了我刚刚写的内容之外,我没有书面证据;主要是来自与他们的 session )。 CNG 具有对开发人员更加友好的 API,并且功能更强大。 CNG 在 Windows Vista 中重新引入,因此它在每个受支持的 Windows 版本中都可用。 CAPI 不再服务于“嗯,它有更多的覆盖范围”,它只是“旧的、粗糙的、遗留的 API”(除非您正在为不受支持的操作系统编写代码,例如 XP)。

如果您使用 CAPI,我不知道您为什么要使用 SChannel 提供程序。通过 MS_ENH_RSA_AES_PROV 的 PROV_RSA_AES 是 CAPI 具有的功能最强大的 RSA(基于 SHA-2 的 PKCS 签名)。但与 CNG 中的软件提供商相比(PSS 签名、具有 SHA-2 的 OAEP,并支持大于 2^32 的公共(public)指数值(好吧,这不是常见需求,但这是 CNG 修复的)),它已经过时了。

关于CryptoAPI RSA Schannel 提供程序错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45211765/

相关文章:

c - 在 C 中将标准输入与 select() 结合使用

c - 具有自己的内存空间的Linux多线程可能吗?

java - Java-使用现有的公钥文件加密字符串

asp.net - healthMonitoring 中的提供者类获取内部异常

asp.net - 使用 CAS 和 ASP.NET 成员(member)提供程序后端进行 SSO

c - 为什么它与第二个版本同时运行?

c - 为什么 while 写在这里没有 body ?

java - 解码加密消息

java - 不兼容的类型 : byte[] cannot be converted to byte

flutter - 将 ChangeNotifier 从 provider 迁移到 hooks_riverpod