web-dev-qa-db-ja.com

PKCS#12バイト配列からX509Certificate2を構築するには、どのようにCryptographicException( "The system cannot find the file ..")をスローできますか?

バイト配列のPKCS#12 blobから_X509Certificate2_を構築しようとしていますが、かなり不可解なエラーが発生します。このコードは、Windows XPの管理者権限を持つデスクトップアプリケーションで実行されています。

スタックトレースは次のとおりですが、__LoadCertFromBlob_が[MethodImpl(MethodImplOptions.InternalCall)]とマークされているため、トラブルシューティングに失敗しました。

_System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
  at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(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)
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
_

EDIT:BLOBは BouncyCastle for C# によって生成された真のPKCS#12であり、RSA秘密鍵と証明書(自己-署名済みまたは最近CAに登録済み)-私がしようとしているのは、秘密鍵と証明書をBouncyCastleライブラリからSystem.Security.Cryptographyライブラリに変換することです。一方からエクスポートし、もう一方にインポートします。このコードは、試されたシステムの大部分で動作します。そのコンストラクターからスローされる特定のエラーを見たことがありません。それは、その1つのボックスのある種の環境の奇妙さかもしれません。

EDIT 2:エラーは別の都市の別の環境で発生しており、ローカルで再現することができないため、結果的に壊れたXPインストールまでそれをチョークで書きます。

あなたが尋ねたので、しかし、ここに問題の断片があります。このコードは、BouncyCastle表現の秘密鍵と証明書を取得し、同じ識別名の以前の証明書を個人鍵ストアから削除し、新しいPKCS#12 Blobを介して新しい秘密鍵と証明書を個人鍵ストアにインポートします。

_// open the personal keystore
var msMyStore = new X509Store(StoreName.My);
msMyStore.Open(OpenFlags.MaxAllowed);

// remove any certs previously issued for the same DN
var oldCerts =
    msMyStore.Certificates.Cast<X509Certificate2>()
        .Where(c => X509Name
                        .GetInstance(Asn1Object.FromByteArray(c.SubjectName.RawData))
                        .Equivalent(CurrentCertificate.SubjectDN))
        .ToArray();
if (oldCerts.Length > 0) msMyStore.RemoveRange(new X509Certificate2Collection(oldCerts));

// build a PKCS#12 blob from the private key and certificate
var pkcs12store = new Pkcs12StoreBuilder().Build();
pkcs12store.SetKeyEntry(_Pkcs12KeyName,
                        new AsymmetricKeyEntry(KeyPair.Private),
                        new[] {new X509CertificateEntry(CurrentCertificate)});
var pkcs12data = new MemoryStream();
pkcs12store.Save(pkcs12data, _Pkcs12Password.ToCharArray(), Random);

// and import it.  this constructor call blows up
_MyCertificate2 = new X509Certificate2(pkcs12data.ToArray(),
                                       _Pkcs12Password,
                                       X509KeyStorageFlags.Exportable);
msMyStore.Add(_MyCertificate2);
msMyStore.Close();
_
37
Jeffrey Hantin

PKCS#12またはPFXファイルのみをお持ちですか?マイクロソフトの世界でも同じですが、他の人は別のことを考えています( http://www.drh-consultancy.demon.co.uk/pkcs12faq-old.html#PFX を参照)。

あなただけに従うことができます

X509Certificate2 cert = X509Certificate2(byte[] rawData, "password");
X509Certificate2 cert2 = X509Certificate2(byte[] rawData, "password",
              X509KeyStorageFlags.MachineKeySet |
              X509KeyStorageFlags.PersistKeySet |
              X509KeyStorageFlags.Exportable);

http://msdn.Microsoft.com/en-us/library/ms148418.aspx を参照)または

X509Certificate2 cert = X509Certificate2("C:\Path\my.pfx", "password");

http://msdn.Microsoft.com/en-us/library/ms148420.aspx および http://msdn.Microsoft.com/en-us/library/ms148442を参照) .aspx いくつかのフラグを使用する必要がある場合)

[〜#〜] updated [〜#〜]:例外スタックトレースだけでなく、コードフラグメントを挿入すると便利です。

どのX509KeyStorageFlagsを使用しますか? Process Monitor を使用して、X509Certificate2コンストラクターを見つけることができなかったファイルを見つけることができます。たとえば、Windowsに現在のユーザーのデフォルトのキーコンテナがない可能性がありますXP問題があります。作成してインポートを再試行できます。

43
Oleg

同じ問題が発生しました。

これによると kb記事 問題は、コンストラクタが現在のユーザーのプロファイルに証明書をロードしようとすることですが、.Netコードはユーザーを偽装していたため、ユーザープロファイルをロードしていませんでした。コンストラクターが正しく機能するには、読み込まれたユーザープロファイルが必要です。

記事から:

X509Certificate2クラスコンストラクターは、アプリケーションを実行するユーザーアカウントのユーザープロファイルに証明書をインポートしようとします。多くの場合、ASP.NETおよびCOM +アプリケーションはクライアントを偽装します。その場合、パフォーマンス上の理由から、なりすましユーザーのユーザープロファイルは読み込まれません。そのため、なりすましユーザーの「ユーザー」証明書ストアにアクセスできません。

ユーザープロファイルの読み込みでエラーが修正されました。

10
Zain Rizvi

Windows 2012のWebアプリケーションでこれに遭遇した場合、アプリケーションプールオプションLoad User Profileをtrueに設定すると機能しました。

これを行うには、inetmgr.exeを実行し、適切なアプリケーションプールのAdvanced Settingsに移動して、Load User Profileの下のProcess Modelをtrueに変更します。

4
deerchao

私も同じ問題を抱えていました。

  1. サイトをホストしているサーバーでIISを開きます。
  2. サイトのアプリケーションプールを見つけます。
  3. [詳細設定]をクリックします。
  4. 「ユーザープロファイルの読み込み」をtrueに変更します。 (再起動または再起動が必要な場合があります)

これにより、 cryptoサブシステム が機能します。

enter image description here

3
paqogomez

私はまったく同じ問題を抱えていました。 Windows 2003 x86では、特定のユーザーで実行すると同じコードとデータ/証明書が正常に動作しましたが、別のアカウントでは失敗しました(IISアプリプールの実行にも使用されていました)。

イベントビューアに関連するイベントはありませんはありましたが、Windowsのリソースを使い果たして、失敗したユーザーがユーザーのプロファイルを実際に読み込めなかった(デスクトップが奇妙に見えた)ようです。

再起動により問題が一時的に解決しました。これは問題の永続的な解決策ではありませんが、調査が必要なリソースを消費している他のものが(COM +コンポーネント、ネイティブコードサービスなど)あることを示しています。また、Windowsプラットフォームの不安定性も示しています...

1
Ricardo Pardini