Dot-Net

為什麼我在創建 X509Certificate2 對象時收到拒絕訪問錯誤?

  • November 27, 2020

我們有一些單元測試,其中嵌入了 PFX 證書。這些證書在測試執行期間被讀取並變成X509Certificate2對象。不幸的是,當以非特權使用者身份執行時,我們會遇到Access Denied異常:

using (var s = EmbeddedResourceUtilities.GetEmbeddedResourceAsStream(typeThatContainsEmbeddedResource, certFileName))
{
   if (s == null)
   {

       throw new ApplicationException(String.Format("Embedded certificate {0} for type {1} not found.", certFileName, typeThatContainsEmbeddedResource.FullName));
   }

   try
   {
       var bytes = new byte[s.Length];
       s.Read(bytes, 0, (int)s.Length);
       return new X509Certificate2(bytes);
   }
   catch (Exception ex)
   {
       throw new ApplicationException(String.Format("Error loading embedded certificate {0} for type {1}.", certFileName, typeThatContainsEmbeddedResource.FullName), ex);
   }
}

這是一個例外:

System.Security.Cryptography.CryptographicException:訪問被拒絕。

在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小時)

在 System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(字節

$$ $$在System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob

(字節$$ $$rawData,對象密碼,X509KeyStorageFlags keyStorageFlags)

在 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(字節$$ $$原始數據)

我嘗試修改建構子以使用空密碼和顯式鍵集標誌,但這並不能解決它:

// this doesn't work, either
return new X509Certificate2(bytes, String.Empty, X509KeyStorageFlags.MachineKeySet);

我在其他地方讀到我應該給我的非特權使用者增加對 MachineKeys 目錄的權限,但我不願意這樣做,因為它會允許生產程式碼假設這些權限在測試環境之外的那個目錄上可用。

有沒有辦法允許非特權使用者從文件中載入 X509Certificate?

這是我對正在發生的事情的最佳猜測。

X509Certificate2 建構子在 Machine Keys 目錄中創建臨時公鑰/私鑰對象(我相信是通過 Windows 本地安全機構)。因為我們的非特權使用者無權訪問這些密鑰或機器密鑰目錄,所以測試失敗。

我們的解決方案是更新我們的環境設置腳本以提前安裝這些測試證書,授予非特權使用者權限,並重新編寫測試以從適當的證書儲存載入證書。

在 X509Certificate2 建構子中使用“X509KeyStorageFlags.UserKeySet”標誌對我有幫助。

引用自:https://stackoverflow.com/questions/15285046