如何创建一个最小的虚拟X509Certificate2?

我是一个.NET应用程序的unit testing; 一些unit testing涉及以编程方式生成X509Certificate2对象。

我不关心实际的签名/私钥/validation的东西,我只想拥有一个在检查其字段时不会抛出exception的对象。 我尝试使用无参数构造函数,但是当访问时,一大堆字段会抛出exception。 如调试器中所示:

SubjectName =’(new System.Collections.Generic.Mscorlib_CollectionDebugView(result.Certificates))。Items [0] .SubjectName’抛出类型’System.Security.Cryptography.CryptographicException’的exception

我也尝试在其中传递带有一些随机数的字节数组,但是甚至没有构造(数组是否需要特定的大小?)

那么,问题: 以编程方式生成X509Certificate2对象的最简单(最少代码行)的方法是什么,该对象不会在字段/属性访问时抛出exception?

我建议如下:

  1. 使用makecert生成证书。
  2. 将证书添加到项目中,并将其Build Action更改为Embedded Resource。
  3. 从unit testing设置中的资源加载证书,请参见下文。

码:

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

此时,您应该善于与证书进行交互。 如果您的unit testing有不同的需求,您可以创建不同的变体。

这可能看起来非常h​​acky,这取决于你想要的实用程度……我使用的方法是从机器中获取随机证书。

在以下情况下这很好: – 我知道运行这些测试的每台机器都有一个有效的证书。 – 我正在使用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(); } } 

在兰登的要求下,我使用的解决方案,我自己:

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

这是有效的,因为我在证书中访问的唯一字段是它的SubjectName和Thumbprint,我访问的SubjectName的唯一字段是名称。 我“moled”这些字段的getter方法返回虚拟字符串。 如果你要访问其他字段,你可能需要将它们分解为。

那么,什么是“摩尔人”?

“Moles是.NET中基于委托的测试存根和绕行的轻量级框架.Moles可用于绕过任何.NET方法,包括密封类型中的非虚拟/静态方法。在Visual Studio Gallery中可以免费获取Moles或与Pex捆绑在一起。“

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

还有一种更简单的方法。

  1. 使用MakeCert创建证书或导出任何现有证书。
  2. 在项目中添加证书(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");