CryptoAPI RSA Schannel 提供商错误
CryptoAPI RSA Schannel Provider error
我正在尝试使用 "Microsoft RSA SChannel Cryptographic Provider" 生成数字签名。获取容器句柄后,我使用 CryptGenKey() 生成签名。但是这个函数returns FALSE。
CryptGenKey() 的 dwError returns80090008。
同样适用于任何其他提供程序类型。此外,当我尝试为同一提供商创建密钥交换对时,它工作正常。我做错了什么?
#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 密钥,仅支持 AT_EXCHANGE
。这主要是早期 TLS(当时还是 SSL)的遗留问题,当时使用 RSA 加密交换密钥,而不是使用 RSA 签名签署的 Diffie-Hellman 密钥协议达成一致……然后,大概 "well, everybody knows how the SChannel provider behaves, why change it?"。 (我看到最接近的是 https://msdn.microsoft.com/en-us/library/windows/desktop/aa387690(v=vs.85).aspx,它显示 CALG_RSA_KEYX 而没有谈论 CALG_RSA_SIGN。)
在 CAPI 中,一个 AT_EXCHANGE
密钥可以同时加密和签名,而一个 AT_SIGNATURE
密钥只能进行签名。
总的来说,Windows 密码学团队不鼓励用 C 编写新代码API(除了我刚刚写的,我没有其他书面证据;主要是来自与他们)。 CNG 对开发人员更友好 API,并且功能更强大。 CNG 在 Windows Vista 中重新运回,因此它在每个支持的 Windows 版本中都可用。 CAPI 不再服务于 "well, it has more coverage" 的目的,它只是 "the old, crufty, legacy API"(除非您正在为不受支持的操作系统编写代码,例如 XP)。
如果您使用的是 CAPI,我不知道您为什么要使用 SChannel 提供程序。 PROV_RSA_AES via MS_ENH_RSA_AES_PROV 是 CAPI 拥有的功能最强大的 RSA(基于 SHA-2 的 PKCS 签名)。但与 CNG 中的软件提供商相比,它已经过时了(PSS 签名,带有 SHA-2 的 OAEP,并支持大于 2^32 的 public 指数值(好吧,这不是常见的需求,但它是 CNG 固定的东西)).
我正在尝试使用 "Microsoft RSA SChannel Cryptographic Provider" 生成数字签名。获取容器句柄后,我使用 CryptGenKey() 生成签名。但是这个函数returns FALSE。
CryptGenKey() 的 dwError returns80090008。
同样适用于任何其他提供程序类型。此外,当我尝试为同一提供商创建密钥交换对时,它工作正常。我做错了什么?
#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 密钥,仅支持 AT_EXCHANGE
。这主要是早期 TLS(当时还是 SSL)的遗留问题,当时使用 RSA 加密交换密钥,而不是使用 RSA 签名签署的 Diffie-Hellman 密钥协议达成一致……然后,大概 "well, everybody knows how the SChannel provider behaves, why change it?"。 (我看到最接近的是 https://msdn.microsoft.com/en-us/library/windows/desktop/aa387690(v=vs.85).aspx,它显示 CALG_RSA_KEYX 而没有谈论 CALG_RSA_SIGN。)
在 CAPI 中,一个 AT_EXCHANGE
密钥可以同时加密和签名,而一个 AT_SIGNATURE
密钥只能进行签名。
总的来说,Windows 密码学团队不鼓励用 C 编写新代码API(除了我刚刚写的,我没有其他书面证据;主要是来自与他们)。 CNG 对开发人员更友好 API,并且功能更强大。 CNG 在 Windows Vista 中重新运回,因此它在每个支持的 Windows 版本中都可用。 CAPI 不再服务于 "well, it has more coverage" 的目的,它只是 "the old, crufty, legacy API"(除非您正在为不受支持的操作系统编写代码,例如 XP)。
如果您使用的是 CAPI,我不知道您为什么要使用 SChannel 提供程序。 PROV_RSA_AES via MS_ENH_RSA_AES_PROV 是 CAPI 拥有的功能最强大的 RSA(基于 SHA-2 的 PKCS 签名)。但与 CNG 中的软件提供商相比,它已经过时了(PSS 签名,带有 SHA-2 的 OAEP,并支持大于 2^32 的 public 指数值(好吧,这不是常见的需求,但它是 CNG 固定的东西)).