Как создать минимальный манекен X509Certificate2? - PullRequest
19 голосов
/ 27 июля 2011

Я тестирую приложение .NET; некоторые из модульных тестов включают программную генерацию объектов X509Certificate2.

Мне наплевать на фактическую подпись / закрытый ключ / валидацию, я просто хотел бы иметь объект, который не выдает исключений при проверке его полей. Я попытался использовать конструктор без параметров, но затем целый ряд полей выдает исключения при обращении. Как видно из отладчика:

SubjectName = '(new System.Collections.Generic.Mscorlib_CollectionDebugView (result.Certificates)). Items [0] .SubjectName' вызвало исключение типа 'System.Security.Cryptography.CryptographicException'

Я также пытался передать байтовый массив с некоторыми случайными числами, но он даже не создавался (должен ли массив быть определенного размера?)

Итак, вопрос: Какой самый простой (наименьшее количество строк кода) способ программно сгенерировать объект X509Certificate2, который не будет генерировать исключения при доступе к полю / свойству?

Ответы [ 4 ]

9 голосов
/ 27 июля 2011

Я бы предложил следующее:

  1. Создание сертификата с использованием makecert .
  2. Добавьте сертификат в свой проект и измените его действие по сборке на 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 голосов
/ 16 апреля 2014

Это может показаться очень хакерским, и это зависит от того, насколько прагматичным вы хотите быть ... подход, который я использовал, это просто получить случайный сертификат с машины.

Это было хорошо, когда: - Я знаю, что каждая машина, на которой выполняются эти тесты, имеет действительный сертификат. - Я использовал 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 голос
/ 28 июля 2011

По запросу Лэнгдона, само решение, которое я использовал:

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

Это сработало, потому что единственными полями, к которым я обращался в сертификате, были его SubjectName и Thumbprint, а единственным полем SubjectName, к которому я обращался, было имя. Я «смоделировал» методы getter для этих полей, чтобы они возвращали фиктивные строки. Если бы вам нужно было получить доступ к другим полям, вам, вероятно, нужно было бы приставить их к.

Итак, что такое "родинки"?

"Кроты - это облегченная среда для тестовых заглушек и обходов в .NET, основанная на делегатах. Кроты могут использоваться для обхода любого метода .NET, включая не виртуальные / статические методы в закрытых типах. Кроты свободно доступны Галерея Visual Studio или в комплекте с Pex. "

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

0 голосов
/ 14 декабря 2016

Есть еще один простой способ сделать это.

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