2011-06-17 46 views
20

我有一個的WinForms應用程序消耗WCF,並作爲參數傳遞給函數的證書:X509證書 - 鍵集不存在

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從一個字節數組重新創建,我需要一些特殊的權限來訪問私鑰?

謝謝!

+1

該鏈接可能會幫助你... http://stackoverflow.com/a/39223239/3857542 –

回答

1

我認爲問題在於您需要將密鑰添加到機器的證書存儲區。

32

如果您使用的是Windows Server 2008或Windows 7,那麼您需要獲得讀取私鑰的權限。

  1. 使用FindPrivateKey工具查找路徑。 例如:

FindPrivateKey我LOCALMACHINE -n 「CN = MyCert」 -a

它返回的路徑:C:\ ProgramData \微軟\加密\ RSA \ MachineKeys的[文件名]

  • 轉到該路徑和打開的文件屬性

  • 轉到安全標籤

  • 點擊「編輯」,然後「添加」

  • 在打開的對話框中寫入:IIS應用程序池\ [您的應用程序池名稱],然後單擊OK

  • 現在,您的應用程序池有權讀這個私鑰。

    +1

    設置證書權限的另一種方法是通過證書管理單元,在這裏描述:http:// stackoverflow。 com/a/3176253/844207 – victorvartan

    +0

    無法添加應用程序池 – Lijo

    26

    我面臨這個問題,我的證書在具有私鑰,但我得到這個錯誤(」 鍵集不存在‘)

    原因:您的網站將在’網絡服務運行「帳戶或擁有較少的權限。

    解決方案:更改應用程序池標識爲 「本地系統重置IIS,並再次檢查。如果它開始工作,它是權限/較少的特權問題,您可以模擬,然後使用其他帳戶。

    +1

    也有一種情況,即使您的應用程序池標識是具有正確權限的帳戶,仍需要爲IIS_IUSRS組授予讀取訪問權限如果嘗試訪問應用程序的Application_Start中的私鑰,則完成該操作。 – RMD

    +0

    在我的情況下,我必須將應用程序池標識更改爲「本地系統」,並提供對「IIS_IUSRS」的私鑰訪問。證書需要安裝在本地計算機商店中。 – Amit

    +0

    這對開發人員環境和部署來說更容易。 – Dhanuka777

    4

    Vano Maisuradze答案的作品。如果您正在查找FindPrivateKey工具,它將包含在Windows Communication Foundation(WCF)和適用於.NET Framework 4的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

    然後繼續在瓦諾Maisuradze答案

    7

    我面臨同樣的問題,我不知道如何(恥辱我的),但它的工作:

    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 
    

    我希望喬恩Skeet可以回答這個謎。

    +2

    @所有人請注意,該解決方案適用於.Net 4.6或更高版本,根據MSDN頁面。 –

    0

    默認情況下,應用程序池標識帳戶無權訪問證書存儲。

    您可以更改爲Network Services帳戶,如Vaibhav.Inspired指出的,或者您授予訪問證書的權限。

    要允許訪問執行以下命令:

    WinHttpCertCfg.exe -g -c LOCAL_MACHINE \ MY -s 「IssuedToName」 -a 「帳戶名」

    注:

    - 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選項。