2011-07-26 18 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");