Windows CryptoAPI: CryptSignHash com CALG_SHA_256 e chave privada do MY keystore

Estou tentando gerar assinaturas digitais no Windows (do XP SP3, mas atualmente testando no Windows 7) com o CryptoAPI que será compatível com os seguintes comandos openssl:

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

Desejo usar uma chave privada do keystore "MY" do Windows para assinar.

Consegui assinar arquivos usando o algoritmo de digestão SHA1 usando as seguintes funções CryptoAPI (omitindo parâmetros por questões de brevidade):

CertOpenStore
CertFindCertificateInStore
CryptAcquireCertificatePrivateKey
CryptCreateHash (with CALG_SHA1)
CryptHashData
CryptSignHash

A assinatura gerada é compatível com "openssl dgst -s1 -verify" (uma vez que a ordem dos bytes é revertida).

Meu problema é: quando tento usar CALG_SHA_256 com CryptCreateHash, ele falha com o erro 80090008 (NTE_BAD_ALGID). Ao pesquisar no Googlepor aí, Descobri que precisava usar um provedor específico (PROV_RSA_AES) em vez do provedor padrão. Como eu teria um identificador de provedor, também precisaria substituir CryptAcquireCertificatePrivateKey por CryptGetUserKey. Então eu modifiquei meu programa para ficar assim:

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

Infelizmente, isso não funcionou como esperado: CryptGetUserKey falhou com o erro 8009000D (NTE_NO_KEY). Se eu remover a chamada CryptGetUserKey, o programa será executado até CryptSignHash, que falha com o erro 80090016 (NTE_BAD_KEYSET). Eu sei que o conjunto de chaves existe e funciona bem, pois eu pude usá-lo para assinar o resumo do SHA1.

Tentei adquirir o contexto novamente com informações do certificado que obtive do CertFindCertificateInStore: o melhor que pude fazer foi uma chamada bem-sucedida do CryptGetUserKey, mas o CryptSignHash sempre falhava com o mesmo erro.

A chave privada que estou tentando usar tem 2048 bits, mas não espero que seja um problema, pois funciona com o resumo SHA1. Estou perplexo, então qualquer sugestão seria muito bem-vinda!

questionAnswers(5)

yourAnswerToTheQuestion