无法用RSA-Sha256签名。 WatchData CSP不是CNG(encryptionAPI:下一代)提供者吗?

我正在使用WatchData USB令牌中的证书进行签名。 我使用Microsoft CryptoAPI函数CryptSignMessage 。 如果我将sha1指定为签名的哈希algorithm,则成功。 但是,如果我尝试使用sha256,则会出现“内部错误发生”。

该驱动程序从http://www.watchdata.com/service/usbtoken.jsp下载。 这包含PKCS#11提供程序。

按照http://blogs.msdn.com/b/alejacma/archive/2010/06/02/quot-an-internal-error-ocurred-quot-when-using-sha-2-algorithms-with-signedcms。 aspx这是因为WatchData提供者不是CNG提供者 – (encryptionAPI:下一代)。

NCryptOpenStorageProvider调用失败,下面的程序 – 这似乎表明,它不是一个CNG提供程序。

#include <windows.h> #include <stdio.h> #include <ncrypt.h> int main() { NCRYPT_PROV_HANDLE hProv; SECURITY_STATUS ret = NCryptOpenStorageProvider(&hProv, L"Watchdata Brazil CSP v1.0", 0); if( ret != ERROR_SUCCESS) printf("Failed\n"); else printf("worked\n"); } 

我通过调用CryptEnumProviders APIfind了提供者的名字。

有没有其他方式使用WatchData令牌上的证书来签署RSA-Sha256? 我认为CryptoAPI不需要依靠CSP来进行哈希函数。 哈希是标准函数,CryptoAPI确实具有SHA-2的实现。

在这种情况下,您可以使用OpenSSL来签署数据。 请参阅https://www.openssl.org/docs/crypto/RSA_sign.html

由于您正在使用USB令牌,因此您可以创建一个新的RSA_METHOD结构,该结构将具有从USB令牌进行签名的方法。

您可以尝试以下方法:

  1. 使用OpenSSL来计算SHA256。
  2. 通过使用新的方法重载RSA结构来计算签名以使用您的令牌。

不幸的是,在CryptoAPI中,即使你与签名分开进行哈希,也必须从同一个CSP提供一个哈希对象,而不仅仅是缓冲区中的哈希数据。 在CNG中,这一点已经改变,散列并不是由密钥存储提供者完成的,签名发生在散列缓冲区上,散列在别处完成,例如在一个CNG原始提供者中。 如果一个CNG密钥存储提供程序得到一个意外长度的散列缓冲区,它仍然可能会失败,所以它不会让你免于提供者不知道给定散列类型的问题。

您确定制造商没有生产您可以在设备上使用的CNG密钥存储供应商吗? 我注意到这个页面上的“WatchKey_USB_Token_Admin_Tool”下载有一个CNG密钥存储提供程序。

更新:这个驱动程序没有与OP的设备一起工作。

我看到四个选项:

  1. 请联系制造商的支持,看看他们是否可以为您提供CNG构建这个设备(并检查实际上支持所需的签名机制)
  2. 使用替代设备
  3. 使用设备软件包支持的替代API(如PKCS#11)来执行签名
  4. (只有当你真的需要它时),使用一个由软件包支持的API在自己的CNG供应商中包含你需要的功能