Windows CryptoAPI: CryptSignHash con CALG_SHA_256 y clave privada de MY keytore

Estoy tratando de generar firmas digitales en Windows (desde XP SP3, pero actualmente estoy probando con Windows 7) con CryptoAPI que será compatible con los siguientes comandos openssl:

openssl dgst -sha256 -sign <parameters> (for signing)
openssl dgst -sha256 -verify <parameters> (for validation)

Quiero usar una clave privada del almacén de claves "MY" de Windows para firmar.

Logré firmar archivos usando el algoritmo de resumen SHA1 usando las siguientes funciones de CryptoAPI (omitiendo parámetros por brevedad):

CertOpenStore
CertFindCertificateInStore
CryptAcquireCertificatePrivateKey
CryptCreateHash (with CALG_SHA1)
CryptHashData
CryptSignHash

La firma generada es compatible con "openssl dgst -sha1 -verify" (una vez que se invierte el orden de los bytes).

Mi problema es: cuando intento usar CALG_SHA_256 con CryptCreateHash, falla con el error 80090008 (NTE_BAD_ALGID). Buscando en Googlealrededor, Descubrí que necesitaba usar un proveedor específico (PROV_RSA_AES) en lugar del predeterminado. Como tendría un identificador de proveedor, también necesitaría reemplazar CryptAcquireCertificatePrivateKey por CryptGetUserKey. Así que modifiqué mi programa para que se vea así:

CryptAcquireContext (with PROV_RSA_AES)
CertOpenStore
CertFindCertificateInStore
CryptGetUserKey
CryptCreateHash (with CALG_SHA256)
CryptHashData
CryptSignHash

Desafortunadamente, esto no funcionó como se esperaba: CryptGetUserKey falló con el error 8009000D (NTE_NO_KEY). Si elimino la llamada CryptGetUserKey, el programa se ejecuta hasta CryptSignHash, que falla con el error 80090016 (NTE_BAD_KEYSET). Sé que el conjunto de claves existe y funciona bien, ya que pude usarlo para firmar el resumen SHA1.

Intenté adquirir el contexto nuevamente con información del contexto del certificado que obtuve de CertFindCertificateInStore: lo mejor que pude hacer fue una llamada exitosa CryptGetUserKey, pero CryptSignHash siempre fallaba con el mismo error.

La clave privada que estoy tratando de usar es de 2048 bits, pero no espero que sea un problema ya que funciona con el resumen SHA1. Estoy perdido, por lo que cualquier sugerencia sería bienvenida.

Respuestas a la pregunta(5)

Su respuesta a la pregunta