web-dev-qa-db-ja.com

X509Certificateコンストラクターの例外

//cert is an EF Entity and 
//    cert.CertificatePKCS12 is a byte[] with the certificate.

var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword");

データベースから証明書を読み込むとき、ステージングサーバー(Windows 2008 R2/IIS7.5)で次の例外が発生します。

System.Security.Cryptography.CryptographicException: An internal error occurred.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
   at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)

注:この問題はローカルでは発生しません(Windows 7/Casini)。

どんな洞察も大歓迎です。

67
lukiffer

IISアプリケーションプール構成([アプリケーションプール]> [詳細設定])にアプリケーションプールIDユーザーのユーザープロファイルを読み込む設定があります。falseに設定すると、キーコンテナーはアクセス可能。

したがって、Load User ProfileオプションとしてTrue

App Pool-> Advanced Settings Screen

117
lukiffer

おそらく、Visual Studio/Cassiniから実行している場合、user証明書ストアにアクセスしていますが、バイトから読み込んでいます。これを試して、問題が解決するかどうかを確認してください:

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet);

これにより、IIS(ASP.Netユーザーとして実行され、ユーザーストアへのアクセス権を持たない可能性が高い)がマシンストアを使用するようになります。

このページ はコンストラクターの詳細を説明し、 このページX509KeyStorageFlags列挙。

編集:セカンドリンク from cyphr に基づいて、それは良いかもしれませんアイデア(以前のソリューションが機能しない場合)、いくつかのFlagsAttribute列挙値を次のように結合します。

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword",
    X509KeyStorageFlags.MachineKeySet
    | X509KeyStorageFlags.PersistKeySet
    | X509KeyStorageFlags.Exportable);

さらに、アクセスできる場合は、LocalServiceを使用するようにアプリケーションプールの設定を変更してみてください(その後、AppPoolを再起動します)。これが問題である場合、適切なレベルにアクセス許可を上げることができます。

最後に、 File.WriteAllBytes を書き出すCertificatePKCS12の内容をpfxファイルに追加し、MMC(インポートの成功後に削除できます。これは単にテストするためです。)データが変更されているか、パスワードが間違っています。

56
Chris Benard

このコードを使用してください:

certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File)
                                   , p12FilePassword
                                   , X509KeyStorageFlags.MachineKeySet |
                                     X509KeyStorageFlags.PersistKeySet | 
                                     X509KeyStorageFlags.Exportable);
29
Francisco

Windows 2012 Server R2で、アプリケーションがディスク上のPFXの証明書を読み込めないという問題がありました。管理者としてアプリを実行すると問題なく動作しますが、例外ではアクセスが拒否されたため、アクセス許可の問題である必要がありました。上記のアドバイスをいくつか試しましたが、まだ問題がありました。 certコンストラクターの3番目のパラメーターとして次のフラグを指定すると、私にとってはうまくいくことがわかりました。

 X509KeyStorageFlags.UserKeySet | 
 X509KeyStorageFlags.PersistKeySet | 
 X509KeyStorageFlags.Exportable
6
Michael Balloni

推測するだけでなく、実際に問題を解決できるようにするためには、問題を再現できる必要があります。同じ問題のあるテストPFXファイルを提供できない場合は、自分で問題を調べる必要があります。最初の重要な質問は、PKCS12の秘密鍵部分または証明書自体の公開部分で例外「内部エラーが発生しました」の発生源ですか?

したがって、同じ証明書を使用して、同じ実験を繰り返してエクスポートすることをお勧めします秘密鍵なし(.CERファイルなど):

var certificate = new X509Certificate(cert.CertificateCER);

または

var certificate = new X509Certificate.CreateFromCertFile("My.cer");

問題の発生元が秘密キーであるか、証明書のプロパティであるかを確認すると役立ちます。

CERファイルに問題がある場合は、公開情報のみがあるため、ファイルへのリンクを安全に投稿できます。あるいは、少なくとも実行することができます

CertUtil.exe -dump -v "My.cer"

または

CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx"

(他のオプションも使用できます)、出力の一部をポストします(たとえば、PRIVATEKEYBLOB自体のないプライベートキーのプロパティ)。

1
Oleg

ユーザープロファイルのロードを変更する代わりに、アプリケーションプールにNetwork ServiceIDを使用させることもできます。

LoadUserProfileをIIS pool? に設定するとどうなりますか?)==も参照してください。

1

ローカルマシンのキーストアに.cer証明書をインポートする必要があります。 .p12証明書をインポートする必要はありません。代わりに、Appleによってアカウントに発行された2番目の証明書を使用します。有効な証明書のペアでなければなりません(ファイルシステムに1つ、キーストアに2つ)。もちろん、dllの3つのフラグをすべて設定する必要があります。

0
PanRycho