2011-07-26 19 views
13

我正在測試.NET應用程序的單元;一些單元測試涉及以編程方式生成X509Certificate2對象。如何創建一個最小的虛擬X509Certificate2?

我不關心實際的簽名/私鑰/驗證的東西,我只想有一個對象在檢查其字段時不會拋出異常。我嘗試使用無參數的構造函數,但隨後一堆字段在訪問時會拋出異常。在調試器中看到:

SubjectName ='(new System.Collections.Generic.Mscorlib_CollectionDebugView(result.Certificates))。Items [0] .SubjectName'拋出'System.Security.Cryptography.CryptographicException'類型的異常。

我也試過路過的字節數組,在它的一些隨機數,但甚至沒有構建

所以,問題(不陣列需要一個特定的大小?):什麼是最簡單的(最少的代碼行)以編程方式生成X509Certificate2對象,該對象不會在字段/屬性訪問時拋出異常?

+0

什麼是痣?你能否提供你的最終解決方案作爲答案?我現在正在嘗試做同樣的事情。 – Langdon

+0

我認爲他的意思是一個框架,用於創建微軟研究中的測試存根和彎路。你可以看看這裏:http://research.microsoft.com/en-us/projects/moles/。 – Sascha

回答

8

我建議如下:

  1. 生成使用makecert證書。
  2. 將證書添加到您的項目並將其生成操作更改爲嵌入式資源。
  3. 從單元測試設置中的資源加載證書,請參見下文。

代碼:

byte[] embeddedCert; 
Assembly thisAssembly = Assembly.GetAssembly(typeof(MyType)); 
using (Stream certStream = thisAssembly.GetManifestResourceStream("YourProjectName.localhost.pfx")) 
{ 
    embeddedCert = new byte[certStream.Length]; 
    certStream.Read(embeddedCert, 0, (int)certStream.Length); 
} 

_signingCert = new X509Certificate2(embeddedCert, "password"); 

在這一點上,你要善於儘可能與證書交互去。如果你的單元測試有不同的需求,你可以創建不同的變體。

+1

我想我實際上可以只讀一次*這個字節數組,然後將它作爲字符打印到文件中,然後將其作爲硬編碼字節[]複製粘貼到源代碼中?那不會太壞... – Cephron

+0

是的,那也行。 –

+0

結束使用痣,使其工作,但謝謝你的答案! – Cephron

1

在蘭登的要求,我使用自己的解決方案:

 //Moling test Certificate 
     var cert = new MX509Certificate2(); 
     var subject = new MX500DistinguishedName(); 
     // hookup 
     cert.SubjectNameGet =() => subject; 
     cert.ThumbprintGet =() => "foo"; 
     subject.NameGet =() => "foobar"; 

這工作,因爲我在證書訪問的唯一領域是它的主旨名稱和指紋,我訪問是在主旨名稱的唯一領域名稱。我「調整」這些字段的getter方法以返回虛擬字符串。如果你要訪問其他領域,你可能需要鼴鼠他們。

那麼,什麼是「痣」? 「Moles是一個輕量級的框架,用於在.NET中測試存根和繞行,它基於代表,Moles可用於繞開.NET方法,包括密封類型中的非虛擬/靜態方法。在Visual Studio Gallery上或與Pex捆綁在一起。「

http://research.microsoft.com/en-us/projects/moles/

+1

Jason接受了我的回答,因爲他更一般。 – Cephron

2

這看起來似乎很哈克,這取決於你想如何務實是...我以前是隻抓從機器隨機證書的方法。

這很好: - 我知道每臺運行這些測試的機器都有一個有效的證書。 - 我正在使用GIT,並不想檢查證書的二進制文件 - 我不在乎證書內容 - 我使用的代碼不是模擬友好的,並且明確要求不可僞造的X509Certificate目的。

絕對不是防彈的,但是解鎖了我並解鎖了我的測試場景。

static X509Certificate2 GetRandomCertificate() 
    { 
     X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     st.Open(OpenFlags.ReadOnly); 
     try 
     { 
      var certCollection = st.Certificates; 

      if (certCollection.Count == 0) 
      { 
       return null; 
      } 
      return certCollection[0]; 
     } 
     finally 
     { 
      st.Close(); 
     } 
    } 
+1

這是測試的輝煌。順便提一下,我們是否需要小心密碼? – Timo

0

還有一種更簡單的方法。

  1. 使用MakeCert創建證書或導出任何現有證書。
  2. 在Project(App_Data文件夾)中添加證書。
  3. 按照以下步驟獲取證書。

代碼:

 string certificate = "cert.pfx"; 
     string certPath = string.Format("{0}/App_Data/{1}", HttpRuntime.AppDomainAppPath, certificate); 
     byte[] bytes = Util.FileToArray(certPath); 
     X509Certificate2 publicKey = new X509Certificate2(bytes, "somepassoword");