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

问题描述 投票:19回答:4

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

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

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

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

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

c# x509certificate x509certificate2
4个回答
9
投票

我建议如下:

  1. 使用makecert生成证书。
  2. 将证书添加到项目中,并将其Build Action更改为Embedded Resource。
  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");

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


3
投票

这可能看起来非常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();
        }
    }

1
投票

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

        //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库中可免费获得Moles或与Pex捆绑在一起。“

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


0
投票

有一种更简单的方法。

  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");
© www.soinside.com 2019 - 2024. All rights reserved.