C# 如何创建最小的虚拟X509Certificate2?
我正在对一个.NET应用程序进行单元测试;一些单元测试涉及以编程方式生成X509Certificate2对象 我不关心实际的签名/私钥/验证内容,我只希望有一个对象在检查其字段时不会抛出异常。我尝试使用无参数构造函数,但是当访问时,一大堆字段会抛出异常。如调试器中所示: SubjectName='(新System.Collections.Generic.Mscorlib_CollectionDebugView(result.Certificates)).Items[0]。SubjectName'引发了类型为'System.Security.Cryptographics.CryptographicException'的异常 我还尝试传递一个字节数组,其中包含一些随机数,但这甚至没有构造(数组是否需要特定大小?)C# 如何创建最小的虚拟X509Certificate2?,c#,x509certificate,x509certificate2,C#,X509certificate,X509certificate2,我正在对一个.NET应用程序进行单元测试;一些单元测试涉及以编程方式生成X509Certificate2对象 我不关心实际的签名/私钥/验证内容,我只希望有一个对象在检查其字段时不会抛出异常。我尝试使用无参数构造函数,但是当访问时,一大堆字段会抛出异常。如调试器中所示: SubjectName='(新System.Collections.Generic.Mscorlib_CollectionDebugView(result.Certificates)).Items[0]。SubjectName'
因此,问题:以编程方式生成X509Certificate2对象的最简单(代码行数最少)方法是什么,它不会在字段/属性访问时引发异常?我建议如下:
在这一点上,您应该能够与证书进行交互。如果您的单元测试有不同的需求,您可以创建不同的变体。应Langdon的要求,我自己使用的解决方案:
//Moling test Certificate
var cert = new MX509Certificate2();
var subject = new MX500DistinguishedName();
// hookup
cert.SubjectNameGet = () => subject;
cert.ThumbprintGet = () => "foo";
subject.NameGet = () => "foobar";
这是因为我在证书中访问的唯一字段是SubjectName和指纹,而我访问的SubjectName的唯一字段是name。我“mole”了这些字段的getter方法以返回伪字符串。如果要访问其他字段,可能需要将它们移动到
那么,“痣”是什么呢
“Moles是一个轻量级框架,用于.NET中基于委托的测试存根和迂回。Moles可用于迂回任何.NET方法,包括密封类型的非虚拟/静态方法。Moles可在Visual Studio Gallery上免费获得或与Pex捆绑。”
这可能看起来很老套,这取决于你想多实际。。。我使用的一种方法是从机器上随机获取一个证书 这很好,因为: -我知道运行这些测试的每台机器都有一个有效的证书。 -我正在使用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();
}
}
还有一种更简单的方法
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");
我想我实际上可以只读取一次字节数组,将其作为字符打印到文件中,然后将其作为硬编码字节[]复制粘贴到源代码中?这还不算太糟糕…@JasonShantz我不明白为什么问这个问题的人会把你的答案标记为“已回答”,而不解释“MyType”是什么???@anhtv13我相信MyType是项目中C类/类型的占位符,该项目包含自签名证书作为嵌入式资源。这允许引用程序集,而程序集又允许将资源作为流读取到embeddedCert字节数组中。一旦有了这个字节数组,就可以为X509Certificate2使用适当的构造函数,在这方面MyType是与资源位于同一项目中的任意对象,如果将证书保留在同一项目中,它可以是UnitTest类本身。注意:“YourProjectName”应该是命名空间(如果项目名称和命名空间不同)。请使用thisAssembly.GetManifestResourceNames()检查一下。什么是Moles?你能提供你的最终解决方案作为答案吗?我现在也在尝试做同样的事情。我想他指的是一个用于创建测试存根的框架,以及Microsoft research的迂回路线。你可以看这里:。接受Jason的答案,而不是我的答案,因为他的答案更一般。这对于测试来说非常棒。我们是否必须小心密码,顺便说一句
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");