web-dev-qa-db-ja.com

X509Certificate-キーセットが存在しません

WCFを使用するWinFormsアプリケーションがあり、証明書を関数にパラメーターとして渡します。

mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...

WCFサービスで、バイトの配列から証明書を再作成しました:

public void SendDocument (byte[] binaryCert)
{   
     X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...

しかし、証明書を使用してxmlに署名すると、「キーセットが存在しません」というエラーが表示されました。

if (cert.HasPrivateKey) // WORKS!!!
{   
    signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...

私のコンピューターでは、アプリケーションは100%動作します!しかし、WebServerでこのエラーが発生しました!

問題は、バイトの配列からX509Certificate2を再作成したとしても、秘密鍵にアクセスするための特別な許可が必要ですか?

ありがとうございました!

29
BrunoXP

Windows Server 2008またはWindows 7を使用している場合は、秘密キーを読み取る権限が必要です。

  1. findPrivateKeyツールを使用してパスを検索します。例えば:

FindPrivateKey My LocalMachine -n​​ "CN = MyCert" –a

次のパスを返します:C:\ ProgramData\Microsoft\Crypto\RSA\MachineKeys [ファイル名]

  1. そのパスに移動し、ファイルのプロパティを開きます

  2. セキュリティタブに移動

  3. 「編集」をクリックしてから「追加」をクリックします

  4. 開いたダイアログで次のように書きます:IIS AppPool\[アプリケーションプール名]]をクリックし、[OK]をクリックします

これで、アプリケーションプールにこの秘密キーを読み取る権限が与えられました。

35
Vano Maisuradze

私はこの問題に直面しました、秘密鍵を持っている私の証明書ですが、このエラーが発生していました( "Keyset does not exist")

原因: Webサイトが「ネットワークサービス」アカウントで実行されているか、権限が低くなっています。

ソリューション:アプリケーションプールIDを「ローカルシステム」、IISのリセットに変更し、再度確認します。動作するようになった場合、それは許可/少ない特権の問​​題であるため、他のアカウントを使用して偽装することもできます。

30

私は同じ問題に直面しており、どのように(私を恥ずかしく思うか)わかりませんが、うまくいきました:

var certificate = new X509Certificate2(filePath, password,
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

certificate.PrivateKey; // before: error "KeySet does not exist"!

using (certificate.GetRSAPrivateKey()) { } // pure black magic

certificate.PrivateKey; // after: just works! lol

誰かがこの謎に答えてくれることを願っています。

12
Kim Tranjan

Vano Maisuradzeの回答が機能します。 FindPrivateKeyツールをお探しの場合、.NET Framework 4のWindows Communication Foundation(WCF)およびWindows Workflow Foundation(WF)のサンプルに含まれています。 http:// www。 Microsoft.com/en-us/download/confirmation.aspx?id=21459

ダウンロードして解凍したら、Visual StudioでプロジェクトWF_WCF_Samples\WCF\Setup\FindPrivateKey\CSを開いてコンパイルします。次に、コマンドプロンプトを開き、WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS\binに移動します。

その後、Vano Maisuradzeの回答に進みます

4
ajliptak

問題は、マシンの証明書ストアにキーを追加する必要があることだと思います。

1
Xint0

アプリケーションプールIDアカウントは、既定では証明書ストアにアクセスできません。

Vaibhav.Inspiredが指すNetwork Servicesアカウントに変更するか、証明書へのアクセスを許可します。

アクセスを許可するには、次のコマンドを実行します。

WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "IssuedToName" -a "AccountName"

ノート:

- The tool may need to be installed first. The setup will place the tool at `C:\Program Files (x86)\Windows Resource Kits\Tools\WinHttpCertCfg.exe`.
- `IssuedName` is the issuer property of the certificate that the application will attempt to access
- The command must be run from command Prompt with elevated privileges

参照: https://support.Microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica ステップ2

また、証明書をインストールするときにMark this key as exportableオプションを有効にする必要があります。

0
ByteArtisan