CryptographicException 'Keyset không tồn tại', mà chỉ thông qua WCF


157

Tôi có một số mã thực hiện cuộc gọi đến dịch vụ web của bên thứ ba được bảo mật bằng chứng nhận X.509.

Nếu tôi gọi mã trực tiếp (sử dụng kiểm tra đơn vị) thì nó hoạt động mà không gặp vấn đề gì.

Khi được triển khai, mã này sẽ được gọi thông qua Dịch vụ WCF. Tôi đã thêm một thử nghiệm đơn vị thứ hai gọi Dịch vụ WCF, tuy nhiên điều này không thành công với một CryptographicExceptionthông báo "Keyset does not exist"khi tôi gọi một phương thức trên dịch vụ web của bên thứ ba.

Tôi cho rằng điều này là do Dịch vụ WCF của tôi sẽ cố gắng gọi dịch vụ web của bên thứ ba bằng cách sử dụng một người dùng khác với chính tôi.

Bất cứ ai có thể làm sáng tỏ thêm về vấn đề này?

Câu trả lời:


168

Nó có thể sẽ là một vấn đề quyền trên chứng chỉ.

Khi chạy thử nghiệm đơn vị, bạn sẽ thực hiện những thử nghiệm trong bối cảnh người dùng của riêng bạn, điều này (tùy thuộc vào kho lưu trữ chứng chỉ ứng dụng khách nào ) sẽ có quyền truy cập vào khóa riêng của chứng chỉ đó.

Tuy nhiên, nếu dịch vụ WCF của bạn được lưu trữ trong IIS hoặc dưới dạng Dịch vụ Windows thì có khả năng nó sẽ chạy trong tài khoản dịch vụ (Dịch vụ mạng, Dịch vụ địa phương hoặc một số tài khoản bị hạn chế khác).

Bạn sẽ cần đặt các quyền thích hợp trên khóa riêng để cho phép tài khoản dịch vụ đó truy cập vào nó. MSDN có các chi tiết


Chạy calcs đã giúp tôi cho một vấn đề hoàn toàn khác cảm ơn
John

3
Tôi chạy APP của mình với tư cách quản trị viên, vấn đề đã biến mất.
derek

1
+1 cho tài liệu MSDN và các bước được liệt kê áp dụng ngay cả cho Ứng dụng web
Naren

Thêm "DỊCH VỤ MẠNG" vào các quyền bảo mật chứng chỉ đã giải quyết vấn đề này cho tôi, cảm ơn!
OpMt

276

Điều này rất có thể là do người dùng IIS không có quyền truy cập vào khóa riêng cho chứng chỉ của bạn. Bạn có thể thiết lập điều này bằng cách làm theo các bước sau ...

  1. Bắt đầu -> Chạy -> MMC
  2. Tệp -> Thêm / Xóa Snapin
  3. Thêm chứng chỉ Snap In
  4. Chọn Tài khoản máy tính, sau đó nhấn tiếp theo
  5. Chọn Máy tính cục bộ (mặc định), sau đó nhấp vào Kết thúc
  6. Trên bảng điều khiển bên trái từ Bảng điều khiển gốc, điều hướng đến Chứng chỉ (Máy tính cục bộ) -> Cá nhân -> Chứng chỉ
  7. Giấy chứng nhận của bạn rất có thể sẽ ở đây.
  8. Nhấp chuột phải vào chứng chỉ của bạn -> Tất cả tác vụ -> Quản lý khóa riêng
  9. Đặt cài đặt khóa riêng của bạn ở đây.

1
Đáng lưu ý rằng đây không phải là một tùy chọn trên Server 2003, trừ khi môi trường của tôi được cấu hình lập dị. Tôi có thể làm điều này trên Windows 7 mặc dù.
Shawn Hubbard

Ý bạn là gì khi đặt khóa riêng ở đây ?? Ý tôi là bạn chỉ có thể thêm người dùng có quyền truy cập đúng không!?
mastervv

10
Cảm ơn, chỉ muốn chỉ ra rằng nếu bạn sử dụng iis7.5 và nhóm ứng dụng chạy dưới dạng ứng dụng, bạn sẽ phải cấp quyền cho người dùng IIS AppPool \ DefaultAppPool cho tệp. Điều này đã khắc phục vấn đề cho tôi.
Ronen Festinger

25
Tôi đã phải cấp phép cho IIS_IUSRS để nó hoạt động với tôi.
TrueEddie

1
nếu bạn nhận được điều này trong khi chạy IIS express, bạn cần cấp quyền đăng nhập của riêng mình.
Jez

38

Tôi đã có vấn đề giống hệt đêm qua. Quyền trên khóa riêng được đặt chính xác, mọi thứ rõ ràng đều ổn trừ khi Keyset không tồn tại lỗi. Cuối cùng, hóa ra chứng chỉ đã được nhập vào cửa hàng người dùng hiện tại trước và sau đó được chuyển đến cửa hàng máy cục bộ. Tuy nhiên - điều đó đã không di chuyển khóa riêng vẫn còn trong

C: \ Tài liệu và thanh toán \ Quản trị viên ...

thay vì

C: \ Tài liệu và thanh toán \ Tất cả người dùng ...

Các quyền rõ ràng trên khóa được đặt chính xác, ASPNET không thể truy cập nó. Khi chúng tôi nhập lại chứng chỉ để khóa riêng được đặt trong nhánh Tất cả người dùng, sự cố đã biến mất.


Vấn đề tương tự. Microsoft cần phải dừng việc để các bozos bảo mật chạy tị nạn.
Paul Stovell

2
Sau 3 giờ bị mất, điều này giải quyết vấn đề của tôi - Cảm ơn bạn. Tôi đã sử dụng mẫu FindPrivateKey và đã bối rối tại sao nó lại xuất hiện trong kho khóa của người dùng của tôi, ngay cả khi nó xuất hiện trong LocalMachine thông qua phần đính vào MMC.
Rob Potter

Tôi sẽ mua cho bạn một cốc bia trong nhiều giờ lãng phí với các quyền như mọi câu trả lời khác nói với tôi.
Scott Scowden

Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn! Tôi đã mất khoảng 2,5 giờ trong cuộc đời nhờ vấn đề khủng khiếp này và tôi chắc chắn rằng tôi sẽ mất 2,5 ngày nếu tôi không nhìn thấy điều này.
Frank Tzan.usis

Tôi đã có cùng một vấn đề ngược lại. Đầu tiên được cài đặt trong Máy cục bộ, sau đó là Người dùng hiện tại. Xóa tất cả các certs khỏi cả hai cửa hàng và cài đặt lại trong Người dùng hiện tại đã sửa nó.
Bart Verkoeijen

24

Để giải quyết Keyset không tồn tại, khi duyệt từ IIS: Nó có thể là sự cho phép riêng tư

Để xem và cho phép:

  1. Chạy> mmc> có
  2. bấm vào tập tin
  3. Nhấp vào Thêm / xóa snap-in
  4. Nhấp đúp chuột vào chứng chỉ
  5. Tài khoản máy tính
  6. Kế tiếp
  7. Hoàn thành
  8. Đồng ý
  9. Nhấp vào Chứng chỉ (Máy tính cục bộ)
  10. Bấm vào cá nhân
  11. Nhấp vào Chứng chỉ

Để cho phép:

  1. Nhấp chuột phải vào tên của chứng chỉ
  2. Tất cả các nhiệm vụ> Quản lý khóa riêng
  3. Thêm và cung cấp đặc quyền (thêm IIS_IUSRS và cung cấp cho nó đặc quyền hoạt động với tôi)

1
Nếu bạn đang chạy trong nhóm ứng dụng, hãy thêm người dùng này thay vào đó "IIS AppPool \ DefaultAppPool"
Sameer Alibhai

Điều này cũng đã giúp tôi. Ngay sau khi tôi cấp cho IIS_IUSRS quyền, nó bắt đầu hoạt động.
Andrej Mohar

18

Có vấn đề tương tự trong khi cố gắng chạy ứng dụng WCF từ Visual Studio. Giải quyết nó bằng cách chạy Visual Studio với tư cách quản trị viên.


11

Tôi đã phải đối mặt với vấn đề này, chứng chỉ của tôi khi có khóa riêng nhưng tôi đã gặp lỗi này ( "Khóa không tồn tại" )

Nguyên nhân: Trang web của bạn đang chạy trong tài khoản "Dịch vụ mạng" hoặc có ít đặc quyền hơn.

Giải pháp : Thay đổi danh tính nhóm ứng dụng thành "Hệ thống cục bộ", đặt lại IIS và kiểm tra lại. Nếu nó bắt đầu hoạt động thì đó là sự cho phép / Vấn đề đặc quyền ít hơn, bạn cũng có thể mạo danh sau đó sử dụng các tài khoản khác.


8

Hoàn toàn bực bội, tôi có cùng một vấn đề và đã thử hầu hết các cách trên. Chứng chỉ đã xuất chính xác có quyền đọc tệp trong đó C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, tuy nhiên, hóa ra nó không có quyền trên thư mục. Đã thêm nó và nó hoạt động


Tôi đã thử rất nhiều thứ để giải quyết vấn đề này, nhưng cái này đã làm được điều đó!
Gyum Fox

wow - KHÔNG mong đợi nó hoạt động nhưng nó đã làm. Tôi đã thêm IISAPPPool\www.mywebsite.comtên người dùng windows cho appool của mình và nó đã hoạt động :-)
Simon_Weaver

bất cứ ai biết tại sao điều này làm việc? là một cái gì đó bị hỏng vì điều này khá tối nghĩa
Simon_Weaver

Đừng làm điều này! Máy chủ rơi vào "trạng thái xấu" nơi các certs đang được nhập và hiển thị với loại nhà cung cấp "Microsoft Software KSP" khi thư mục ..RSA \ MachineKeys thay đổi quyền cơ sở. Thêm chi tiết reddit.com/r/sysadmin/comments/339ogk/ trên .
Dhanuka777

3

Tôi có vấn đề chính xác tương tự quá. Tôi đã sử dụng lệnh

findprivatekey root localmachine -n "CN="CertName" 

kết quả cho thấy khóa riêng nằm trong thư mục c: \ ProgramData thay vì C: \ Documents and settngs \ Tất cả người dùng ..

Khi tôi xóa khóa khỏi thư mục c: \ ProgramData, một lần nữa chạy lệnh findPrivatekey không thành công. I E. nó không tìm thấy chìa khóa

Nhưng nếu tôi tìm kiếm cùng khóa được trả về bởi lệnh trước đó, tôi vẫn có thể tìm thấy khóa trong

C: \ Tài liệu và thanh toán \ Tất cả người dùng ..

Vì vậy, theo hiểu biết của tôi, IIS hoặc WCF được lưu trữ không tìm thấy khóa riêng từ C: \ Documents và giải quyết \ Tất cả người dùng ..


2
Hi liên kết này sẽ cho bạn biết làm thế nào để giải quyết vấn đề này và cũng có thể xác định vị trí findprivatekey công cụ: blogs.msdn.microsoft.com/dsnotes/2015/08/13/...
Tahir Khalid

3

Tôi đã gặp lỗi: CryptographicException 'Keyset không tồn tại' khi tôi chạy ứng dụng MVC.

Giải pháp là: cấp quyền truy cập vào chứng chỉ cá nhân cho tài khoản mà nhóm ứng dụng đang chạy. Trong trường hợp của tôi, đó là thêm IIS_IUSRS và chọn đúng vị trí đã giải quyết vấn đề này.

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

Câu trả lời từ Steve Sheldon đã khắc phục vấn đề cho tôi, tuy nhiên, vì tôi đang cấp quyền cho chứng chỉ kịch bản mà không có gui, tôi cần một giải pháp có thể viết được. Tôi loay hoay tìm nơi cất giữ khóa riêng của mình. Khóa riêng không có trong -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, cuối cùng tôi thấy rằng nó thực sự nằm trong C:\ProgramData\Microsoft\Crypto\Keys. Dưới đây tôi mô tả làm thế nào tôi phát hiện ra rằng:

Tôi đã thử FindPrivateKeynhưng nó không thể tìm thấy khóa riêng và sử dụng powershell $cert.privatekey.cspkeycontainerinfo.uniquekeycontainernamelà null / trống.

May mắn thay, certutil -store myliệt kê các chứng chỉ và cung cấp cho tôi các chi tiết tôi cần để kịch bản giải pháp.

================ 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.

Sau đó tôi đã quét c\ProgramData\Microsoft\Crypto\thư mục và tìm thấy tệp 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a trong C: \ ProgramData \ Microsoft \ Crypto \ Keys .

Cho phép tài khoản dịch vụ của tôi đọc quyền truy cập tệp này đã khắc phục các sự cố cho tôi


1
Sử dụng "certutil -store my" là chìa khóa để giải quyết vấn đề của tôi. Tôi đã sử dụng "Tên bộ chứa duy nhất" để định vị tệp và Trình theo dõi quy trình Sysiternals để khắc phục lỗi "Truy cập bị từ chối" trên tệp chứng chỉ. Trong trường hợp của tôi, tôi đã phải cung cấp quyền truy cập đọc vào tệp chứng chỉ cho người dùng NT Author \ IUSR.
hsop

1

Tôi đã tìm thấy một số thông tin còn thiếu giúp tôi có được dịch vụ WCF của mình với bảo mật cấp Tin nhắn qua "Khóa không tồn tại" mà tôi vẫn chạy vào mặc dù cấp quyền cho tất cả các khóa được tạo từ các ví dụ trên internet.

Cuối cùng tôi đã nhập khóa riêng vào cửa hàng người đáng tin cậy trên máy cục bộ và sau đó cấp cho khóa riêng quyền chính xác.

Điều này điền vào chỗ trống cho tôi và cuối cùng cho phép tôi triển khai dịch vụ WCF với bảo mật cấp Tin nhắn. Tôi đang xây dựng một WCF phải tuân thủ HIPPA.


1

Tôi vừa cài đặt lại chứng chỉ của mình trong máy cục bộ và sau đó nó hoạt động tốt


0

Nếu bạn sử dụng ApplicationPoolIdentity cho nhóm ứng dụng của mình, bạn có thể gặp vấn đề với việc chỉ định quyền cho người dùng "ảo" đó trong trình chỉnh sửa sổ đăng ký (không có người dùng như vậy trong hệ thống).

Vì vậy, hãy sử dụng subinacl - công cụ dòng lệnh cho phép thiết lập ACL của registry hoặc đại loại như thế này.


0

Tôi chỉ muốn thêm một câu trả lời kiểm tra vệ sinh. Tôi đã nhận được cùng một lỗi chính xác ngay cả sau khi cài đặt chứng chỉ vào đúng cửa hàng trên máy của tôi và có tất cả các đặc quyền bảo mật phù hợp cho máy khách. Hóa ra tôi đã trộn lẫn chứng chỉ ứng dụng khách và Chứng chỉ dịch vụ của mình. Nếu bạn đã thử tất cả những điều trên, tôi sẽ kiểm tra lại xem bạn có hai thứ đó không. Khi tôi đã làm điều đó, ứng dụng của tôi đã gọi thành công dịch vụ web. Một lần nữa, chỉ là một kiểm tra vệ sinh.


0

Đã nhận được lỗi này khi sử dụng OpenAM Fedlet trên IIS7

Thay đổi tài khoản người dùng cho trang web mặc định đã giải quyết vấn đề. Lý tưởng nhất, bạn sẽ muốn đây là một tài khoản dịch vụ. Có lẽ ngay cả tài khoản IUSR. Đề nghị tìm kiếm các phương pháp cho IIS cứng để đóng nó hoàn toàn.


0

Tôi đã đạt được điều này trong dự án vải dịch vụ của mình sau khi chứng chỉ được sử dụng để xác thực chống lại kho tiền chính của chúng tôi đã hết hạn và được xoay, điều này đã thay đổi dấu vân tay. Tôi đã gặp lỗi này vì tôi đã lỡ cập nhật dấu vân tay trong tệp applicationManifest.xml trong khối này, chính xác là những gì các câu trả lời khác đã đề xuất - để cung cấp cho NETWORK SERVICE (tất cả các phiên bản cũ của tôi chạy dưới dạng, cấu hình chuẩn cho cụm dịch vụ azure) truy cập vào vị trí cửa hàng chứng nhận của LOCALMACHINE \ MY.

Lưu ý giá trị thuộc tính "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

Đây là giải pháp duy nhất làm việc cho tôi.

    // 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));

Tham khảo 1

Tham khảo 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.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.