質問

Windows(XP SP3から、しかし現在Windows 7でテストしている)でデジタル署名を生成しようとしています。

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

署名するために「My」キーストア「My」キーストアから秘密キーを使用したいと思います。

次のCryptoAPI関数を使用して、SHA1 Digestアルゴリズムを使用してファイルに署名することができました(Brevityのパラメーターを省略):

CertOpenStore
CertFindCertificateInStore
CryptAcquireCertificatePrivateKey
CryptCreateHash (with CALG_SHA1)
CryptHashData
CryptSignHash

生成された署名は、「OpenSSL DGST -Sha1 -Verify」(バイト順序が逆転したら)と互換性があります。

私の問題は、cryptcreatehashでcalg_sha_256を使用しようとすると、エラー80090008(nte_bad_algid)で失敗します。グーグルで その周り, 、デフォルトのプロバイダー(Prov_RSA_AES)の代わりに、特定のプロバイダー(Prov_RSA_AES)を使用する必要があることがわかりました。プロバイダーハンドルを持っているので、CryptaCirecertificatePrivateKeyをCryptgetuserkeyに置き換える必要もあります。だから私は自分のプログラムを次のように変更しました:

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

残念ながら、これは期待どおりに機能しませんでした。CryptgetUserKeyはエラー8009000D(NTE_NO_KEY)で失敗しました。 CryptgetUserKeyコールを削除すると、プログラムはcryptsignhashまで実行されます。これはエラー80090016(nte_bad_keyset)で失敗します。 Keysetが存在し、SHA1ダイジェストに署名するために使用できるため、正常に機能することは知っています。

CertFindCertificateInStoreから得た証明書のコンテキストからの情報を使用して、コンテキストを再度取得しようとしました。私ができる最善のことは、CryptgetUserKeyの呼び出しを成功させましたが、Cryptsignhashは常に同じエラーで失敗します。

私が使用しようとしている秘密鍵は2048ビットの長さですが、SHA1ダイジェストで動作するため、問題になるとは思いません。私は途方に暮れているので、どんな提案でも大歓迎です!

役に立ちましたか?

解決

問題は、プロバイダーがプライベートキーが保存されている「Windowsの「Know」」の証明書である可能性が最も高いことです。証明書をインポートすると、キーを特定のプロバイダータイプ(おそらくprov_rsa_full)に入れます。その後、証明書を介してキーにアクセスしようとすると、おそらく同じプロバイダータイプになります。

おそらく、証明書に関連するコンテキストを開く必要があります(をご覧ください certgetCertificateContextProperty CERT_KEY_PROV_HANDLE_PROP_IDオプションで)。そのハンドルを使用すると、元のプロバイダーコンテキストからキーをエクスポートし、新しいProv_RSA_AES ONEにリンプすることを試みることができます(キーがエクスポート可能であると仮定)。

他のヒント

80090008 ベースプロバイダーがSHA256、SHA384、SHA512をサポートしていないために引き起こされます。 CryptAcquireContext(hProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0);

以前の答えのほとんどには、本当の答えの一部があります。これを行う方法は、主要なコンテナと「Microsoft Enhanced RSAおよびAES暗号プロバイダー」を使用するHcRyptProvを取得することです。

CryptAcquireContext(&hCryptProv, <keyContainerName>, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_SILENT)

結果のHcryptProvを使用して、サポートされているすべてのSHA2:256、384、512で作成されたハッシュに署名できます。

キーコンテナ名は、certgetCertificatecontextProperty()を使用して取得できます。

この手法は、秘密鍵がエクスポートできなくても機能します。

証明書を見つけたら、電話をかけてみてください CertGetCertificateContextPropertyCERT_KEY_PROV_INFO_PROP_ID キーを使用してプロバイダーとコンテナの名前を取得するには。電話してみてください CryptAcquireContext これらの名前で、しかし指定します PROV_RSA_AES プロバイダータイプとして。

また、プロバイダー名を「Microsoft Enhanced RSAおよびAES暗号プロバイダー」に置き換えることもできますが、プロバイダーが他のMicrosoftプロバイダーの1つでない限り、これは間違いなく機能しません。

この投稿を見つける前に、最近同様の問題に遭遇しました。この投稿は問題を理解するのに役立ちますが、解決策を与えませんでした。最後に、Googleの助けを借りて、私は問題を解決しました。この質問は5年前に尋ねられましたが、私はそれが他の人に役立つ場合に備えて私の解決策をここに書きます。

まず、私の問題について説明しましょう。SSLサーバーとして機能するデバイスにOpenSSL 0.9.8を移植しましたが、Microsoft WindowsでSSLクライアントとして実行されているプログラムも提供しました。クライアント/サーバーモデルは、クライアント証明書認証をサポートしています。クライアントは、Microsoft Crypto-APIを呼び出して、OpenSSLでRSA_Methodを実装して証明書認証をサポートします。これまでのところ、OpenSSLライブラリを0.9.8から1.0.2にアップグレードする前に非常に良い TLSV1.2. 。 TLSV1.2が選択された場合、クライアント証明書認証は常に失敗しました。デバッグ後、問題はクライアントプログラムのRSA_SIGNメソッドにあることがわかりました。この方法は、Hash結果に署名して、SSLクライアント検証メッセージで使用されるデジタル署名を取得します。署名操作は使用して計算されます CertFindCertificatePrivateKey/CryptCreateHash/CryptSetHashParam/CryptSignHash この質問が説明したAPI。エラーはCryptCreatehashコールで発生しました。ここでは、要求されたハッシュメソッドはSHA-384ですが、certfindCertificatePrivateKeyによって取得されたhcryptoprovはCSPに対応していました(Microsoft Enhanced Cryptographic Provider v1.0)SHA-2ハッシュメソッドをサポートしていません。

これは本当の退屈な説明です。あなたがまだ読み続けているなら、あなたも同様の問題に会ったと思います。私の解決策を紹介させてください。

私の最初の反応は、HashアルゴリズムをSHA-1にダウングレードするためにSSLネゴシエーションパラメーションを調整することでしたが、失敗しました。 SHA-2ハッシュはTLSV1.2に義務的であるようです。また、証明書の秘密鍵で暗号化することにより、署名操作を達成しようとしましたが、これも失敗しました。 Crypto-APIは、証明書の秘密キー暗号化のインターフェイスを提供しません(これについてはわかりませんが、見つかりませんでした。)結果の2日間の試みの後、このWebページを見つけました。 http://www.componentspace.com/forums/topic1578.aspx. 。トンネルの端にある光のようなものです。証明書は、SHA-2をサポートしていないCSPで拘束されます。SHA-2をサポートするCSPに変換できれば、すべてが問題ありません。リンクが壊れた場合、ここで変換方法を貼り付けます。

openssl pkcs12 -export -in idp.pem -out new-idp.pfx -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider"

Webページによると、.pfx証明書ファイルを再構築しました。証明書を再輸入しました。その後、問題が解決します。

これが役立つことを願っています。 :-)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top