CryptographicException 'キーセットが存在しません'が、WCFを介してのみ


157

X.509証明書を使用して保護されたサードパーティのWebサービスを呼び出すコードがあります。

(単体テストを使用して)コードを直接呼び出すと、問題なく機能します。

展開すると、このコードはWCFサービスを介して呼び出されます。WCFサービスを呼び出す2番目の単体テストを追加しましたが、サードパーティのWebサービスでメソッドを呼び出すとCryptographicException、メッセージが表示されて失敗し"Keyset does not exist"ます。

これは、私のWCFサービスが自分とは別のユーザーを使用してサードパーティのWebサービスを呼び出そうとしているためだと思います。

誰もがこの問題に追加の光を当てることができますか?

回答:


168

おそらく証明書のアクセス許可の問題でしょう。

ユニットテストを実行すると、独自のユーザーコンテキストで実行されます(クライアント証明書がどのストアにあるかによって異なります)は、その証明書の秘密鍵にアクセスできます。

ただし、WCFサービスがIISまたはWindowsサービスとしてホストされている場合は、サービスアカウント(ネットワークサービス、ローカルサービス、またはその他の制限されたアカウント)で実行されている可能性があります。

サービスアカウントが秘密鍵にアクセスできるようにするには、秘密鍵に適切な権限を設定する必要があります。MSDNに詳細あります


calcsを実行すると、まったく別の問題のおかげで助けになりました
John

3
APPを管理者として実行すると、問題は解決しました。
derek

1
MSDNドキュメントの +1と記載されている手順は、Webアプリケーションにも適用されます
Naren

証明書のセキュリティ権限に「ネットワークサービス」を追加すると、この問題は解決しました。ありがとうございます。
OpMt

276

これは、IISユーザーが証明書の秘密キーにアクセスできないことが原因と考えられます。次の手順でこれを設定できます...

  1. スタート->実行-> MMC
  2. ファイル->スナップインの追加/削除
  3. 証明書スナップインを追加する
  4. コンピュータアカウントを選択し、次に
  5. [ローカルコンピュータ](デフォルト)を選択し、[完了]をクリックします
  6. コンソールルートの左側のパネルで、[証明書(ローカルコンピューター)]-> [個人]-> [証明書]に移動します。
  7. 証明書はおそらくここにあります。
  8. 証明書を右クリック->すべてのタスク->秘密鍵の管理
  9. ここで秘密鍵の設定を行います。

1
私の環境が奇抜に構成されていない限り、これはServer 2003のオプションではないことに注意してください。私はWindows 7でこれを行うことができます。
Shawn Hubbard、

ここで秘密鍵を設定するとはどういう意味ですか?つまり、アクセス権を持つユーザーのみを追加できます!?
mastervv 2012年

10
ありがとう、iis7.5を使用していて、アプリケーションプールがapplicationpoolidentityとして実行されている場合は、IIS AppPool \ DefaultAppPoolユーザー権限をファイルに付与する必要があることを指摘したかっただけです。これで問題が解決しました。
Ronen Festinger 2013

25
IIS_IUSRSが動作するように許可する必要がありました。
TrueEddie 2014

1
IIS Expressの実行中にこれを取得する場合は、独自のログイン許可を与える必要があります。
Jez、2015年

38

昨夜も同じ問題がありました。秘密キーのアクセス許可は正しく設定されていました。キーセットが存在しないというエラーを除いて、すべてが明らかに問題ありませんでした。最終的に、証明書は最初に現在のユーザーストアにインポートされ、その後ローカルマシンストアに移動されたことがわかりました。ただし、それでも秘密鍵は移動されませんでした。

C:\ Documents and settngs \ Administrator ...

の代わりに

C:\ Documents and settngs \ All users ...

キーのアクセス許可は正しく設定されていましたが、ASPNETはそれにアクセスできませんでした。証明書を再インポートして秘密キーをAll usersブランチに配置すると、問題は解消しました。


同じ問題。マイクロソフトは、セキュリティボゾが亡命を実行するのを止める必要があります。
Paul Stovell、2011年

2
3時間が失われた後、これで私の問題は解決しました-ありがとう。私はFindPrivateKeyサンプルを使用しましたが、MMCスナップインを介してLocalMachineに表示された場合でも、ユーザーのキーストアにあるように見えました。
ロブポッター

私はあなたに他のすべての答えが私に言ったように許可をいじる時間を浪費してビールを買います。
Scott Scowden 2013

ありがとう、ありがとう、ありがとう!私はこの恐ろしい問題のおかげで私の人生の約2.5時間を失いました、そして私がこれを見なければ、私は2.5日を失っていただろうと確信しています。
フランクTzanabetis 2013年

私は逆に同じ問題を抱えていました。最初にローカルマシンにインストールされ、次に現在のユーザーにインストールされます。両方のストアからすべての証明書を削除し、現在のユーザーの下に再インストールすると修正されました。
Bart Verkoeijen 2017

24

IISからブラウジングするときに「キーセットが存在しない」を解決するには: プライベートアクセス権の可能性があります

表示して許可を与えるには:

  1. 実行> mmc>はい
  2. ファイルをクリック
  3. スナップインの追加/削除をクリックします…
  4. 証明書をダブルクリックします
  5. コンピューターアカウント
  6. 仕上げ
  7. OK
  8. 証明書(ローカルコンピュータ)をクリックします。
  9. 個人をクリックします
  10. 証明書をクリックします

許可を与えるには:

  1. 証明書の名前を右クリックします
  2. すべてのタスク>秘密鍵の管理…
  3. 特権を追加して与える(IIS_IUSRSを追加して特権を与えるとうまくいきます)

1
アプリプールで実行している場合は、代わりにこのユーザーを追加します "IIS AppPool \ DefaultAppPool"
Sameer Alibhai

これも私を助けました。IIS_IUSRSにアクセス許可を与えるとすぐに、IIS_IUSRSが機能し始めました。
Andrej Mohar 2018年

18

Visual StudioからWCFアプリを実行しようとしたときに同じ問題が発生しました。管理者としてVisual Studioを実行して解決しました。


11

私はこの問題に直面しましたが、証明書には秘密鍵がありますが、このエラーが発生しました(「キーセットが存在しません」

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

解決策:アプリケーションプールのIDを「ローカルシステム」に変更し、IISをリセットして、もう一度確認します。それが機能し始めたら、それは許可/少ない特権の問​​題です、あなたは他のアカウントも使用して偽装することができます。


8

完全にイライラして、私は同じ問題を抱えており、上記のほとんどを試しました。エクスポートされた証明書には、でファイルを読み取る権限が正しくありましたがC:\ProgramData\Microsoft\Crypto\RSA\MachineKeys、フォルダーに対する権限がなかったことが判明しました。追加して機能しました


私はこの問題を解決するために非常に多くのことを試みましたが、これはトリックをしました!
Gyum Fox

うわー-それがうまくいくとは思っていませんでしたが、うまくいきました。私IISAPPPool\www.mywebsite.comは自分のアプリケーションのWindowsユーザー名を追加し、それが機能しました:-)
Simon_Weaver

なぜこれが機能するのか誰か知っていますか?これはかなりあいまいなので、破損しています
Simon_Weaver

これを行わないでください!..RSA \ MachineKeysフォルダーの基本的なアクセス許可が変更されると、サーバーが "不良状態"になり、証明書がインポートされ、 "Microsoft Software KSP"プロバイダーの種類で表示されます。詳細については、reddit.com / r / sysadmin / comments / 339ogk /…をご覧ください
Dhanuka777 2017年

3

私もまったく同じような問題を抱えています。コマンドを使用しました

findprivatekey root localmachine -n "CN="CertName" 

結果は、秘密鍵がC:\ Documentsおよびsettngs \ All usersではなくc:\ ProgramDataフォルダーにあることを示しています。

c:\ ProgramDataフォルダーからキーを削除すると、findPrivatekeyコマンドを再度実行しても成功しません。すなわち。キーが見つかりません。

しかし、以前のコマンドで返された同じキーを検索した場合でも、キーを見つけることができます

C:\ Documents and settngs \ All users ..

そのため、私の理解では、IISまたはホストされているWCFはC:\ Documentsおよびsettngs \ All usersから秘密キーを見つけていません。


2
こんにちは、このリンクは、この問題を解決しても、検索する方法を教えてくれますfindprivatekey:ツール blogs.msdn.microsoft.com/dsnotes/2015/08/13/...
タヒルハリド

3

MVCアプリケーションを実行すると、CryptographicException 'Keyset does not exist'というエラーが発生しました。

解決策は、アプリケーションプールを実行しているアカウントに個人証明書へのアクセス権を与えることでした。私の場合、IIS_IUSRSを追加し、正しい場所を選択することでこの問題は解決しました。

RC on the Certificate - > All tasks -> Manage Private Keys -> Add->  
For the From this location : Click on Locations and make sure to select the Server name. 
In the Enter the object names to select : IIS_IUSRS and click ok. 

2

Steve Sheldonからの回答で問題が解決しましたが、GUIを使用せずに証明書のアクセス許可をスクリプト化しているため、スクリプト可能なソリューションが必要でした。私は自分の秘密鍵がどこに保管されているかを見つけるのに苦労しました。秘密鍵は含まれていませんでしたが-C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys、最終的には実際に含まれていることがわかりましたC:\ProgramData\Microsoft\Crypto\Keys。以下に私がそれを見つけた方法を説明します:

試しましたFindPrivateKeyが、秘密鍵が見つかりませんでした。Powershellを使用すると、$cert.privatekey.cspkeycontainerinfo.uniquekeycontainernamenull / emptyでした。

さいわい、certutil -store my証明書を一覧表示し、ソリューションのスクリプトを作成するために必要な詳細を教えてくれました。

================ Certificate 1 ================ Serial Number: 162f1b54fe78c7c8fa9df09 Issuer: CN=*.internal.xxxxxxx.net NotBefore: 23/08/2019 14:04 NotAfter: 23/02/2020 14:24 Subject: CN=*.xxxxxxxnet Signature matches Public Key Root Certificate: Subject matches Issuer Cert Hash(sha1): xxxxa5f0e9f0ac8b7dd634xx Key Container = {407EC7EF-8701-42BF-993F-CDEF8328DD} Unique container name: 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a ##* ^-- filename for private key*## Provider = Microsoft Software Key Storage Provider Private key is NOT plain text exportable Encryption test passed CertUtil: -store command completed successfully.

次に、c\ProgramData\Microsoft\Crypto\フォルダーをスキャンし、C:\ ProgramData \ Microsoft \ Crypto \ Keysに8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128aファイルを見つけました。

サービスアカウントに読み取りアクセス権を付与すると、このファイルで問題が解決します


1
「certutil -store my」を使用することが私の問題を解決するための鍵でした。「一意のコンテナ名」を使用してファイルを見つけ、Sysinternals Process Monitorを使用して証明書ファイルの「アクセス拒否」エラーをトラブルシューティングしました。私の場合、NT Authority \ IUSRユーザーに証明書ファイルへの読み取りアクセスを提供する必要がありました。
hsop

1

インターネット上の例から生成されたすべてのキーへのアクセス許可を付与しているにもかかわらず、「キーセットが存在しない」というメッセージレベルのセキュリティを備えたWCFサービスを実行するのに役立ついくつかの欠けている情報を見つけました。

最後に、秘密鍵をローカルマシンの信頼できる人物ストアにインポートし、秘密鍵に適切な権限を付与しました。

これにより空白が埋められ、メッセージレベルのセキュリティでWCFサービスを実装できるようになりました。HIPPAに準拠する必要があるWCFを構築しています。



0

アプリケーションプールにApplicationPoolIdentityを使用する場合、レジストリエディターでその「仮想」ユーザーのアクセス許可を指定する際に問題が発生する可能性があります(システムにはそのようなユーザーは存在しません)。

そのため、subinacl-レジストリACLの設定を可能にするコマンドラインツールなどを使用します。


0

健全性チェックの回答を追加したかっただけです。証明書をマシンの適切なストアにインストールし、クライアントに適切なセキュリティ権限をすべて与えた後でも、まったく同じエラーが発生しました。clientCertificateとサービス証明書を混同していることがわかりました。上記のすべてを試した場合は、これら2つがまっすぐかどうかをもう一度確認します。これを実行すると、アプリケーションがWebサービスを正常に呼び出すことができました。繰り返しますが、ただの正気チェッカーです。


0

IIS7でopenAM Fedletを使用しているときにこのエラーを受け取りました

デフォルトのWebサイトのユーザーアカウントを変更すると、問題が解決しました。理想的には、これをサービスアカウントにする必要があります。おそらくIUSRアカウントです。IISを完全に特定するための強化の方法を探すことを提案します。


0

Key Vaultに対する認証に使用される証明書の有効期限が切れてローテーションされたため、サービスファブリックプロジェクトでこれにぶつかり、サムプリントが変更されました。このエラーが発生したのは、このブロックのapplicationManifest.xmlファイルでサムプリントを更新しなかったためです。このブロックは、他の回答が示唆していることを正確に実行します。 LOCALMACHINE \ MY証明書ストアの場所にアクセスします。

「X509FindValue」属性値に注意してください。

<!-- this block added to allow low priv processes (such as service fabric processes) that run as NETWORK SERVICE to read certificates from the store -->
  <Principals>
    <Users>
      <User Name="NetworkService" AccountType="NetworkService" />
    </Users>
  </Principals>
  <Policies>
    <SecurityAccessPolicies>
      <SecurityAccessPolicy ResourceRef="AzureKeyvaultClientCertificate" PrincipalRef="NetworkService" GrantRights="Full" ResourceType="Certificate" />
    </SecurityAccessPolicies>
  </Policies>
  <Certificates>
    <SecretsCertificate X509FindValue="[[THIS KEY ALSO NEEDS TO BE UPDATED]]" Name="AzureKeyvaultClientCertificate" />
  </Certificates>
  <!-- end block -->


0

これは私のために働いた唯一の解決策です。

    // creates the CspParameters object and sets the key container name used to store the RSA key pair
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = "MyKeyContainerName"; //Eg: Friendly name

    // instantiates the rsa instance accessing the key container MyKeyContainerName
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
    // add the below line to delete the key entry in MyKeyContainerName
    // rsa.PersistKeyInCsp = false;

    //writes out the current key pair used in the rsa instance
    Console.WriteLine("Key is : \n" + rsa.ToXmlString(true));

リファレンス1

リファレンス2


0
This issue is got resolved after adding network service role.

CERTIFICATE ISSUES 
Error :Keyset does not exist means System might not have access to private key
Error :Enveloped data  
Step 1:Install certificate in local machine not in current user store
Step 2:Run certificate manager
Step 3:Find your certificate in the local machine tab and right click manage privatekey and check in allowed personnel following have been added:
a>Administrators
b>yourself
c>'Network service'
And then provide respective permissions.

## You need to add 'Network Service' and then it will start working.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.