Как создать минимальный фиктивный X509Certificate2?

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

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

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

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

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


person Cephron    schedule 26.07.2011    source источник
comment
Что такое родинки? Можете ли вы предоставить свое окончательное решение в качестве ответа? Я пытаюсь сделать то же самое сейчас.   -  person Langdon    schedule 28.07.2011
comment
Я предполагаю, что он имеет в виду основу для создания тестовых заглушек и обходных путей из исследований Microsoft. Вы можете посмотреть здесь: research.microsoft.com/en-us/projects/moles< /а>.   -  person Sascha    schedule 29.07.2011


Ответы (4)


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

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

На этом этапе вы должны быть готовы к взаимодействию с сертификатом. Вы можете создавать разные варианты, если ваши модульные тесты имеют разные потребности.

person Jason Shantz    schedule 26.07.2011
comment
Я полагаю, я мог бы просто прочитать этот массив байтов один раз, напечатать его в файл в виде символов, а затем скопировать и вставить его в исходный код как жестко закодированный byte[]? Было бы не плохо... - person Cephron; 27.07.2011
comment
В итоге использовал Moles, чтобы заставить его работать, но спасибо за полезный ответ! - person Cephron; 28.07.2011
comment
@Langdon Moles — это изоляционная структура от MS. Раньше он был частью среды тестирования Pex. Несколько лет назад он был извлечен и теперь доступен как автономный фреймворк. - person Safor; 10.10.2014
comment
@JasonShantz Я не понимаю, почему люди, задающие этот вопрос, отмечают ваш ответ как ответ без объяснения причин, что такое MyType??? - person anhtv13; 07.06.2016
comment
@anhtv13 anhtv13 Я считаю, что MyType — это заполнитель для класса/типа C# в проекте, который содержит самозаверяющий сертификат в качестве встроенного ресурса. Это позволяет ссылаться на сборку, что, в свою очередь, позволяет считывать ресурс как поток в массив байтов embeddedCert. Получив этот массив байтов, вы можете использовать соответствующий конструктор для X509Certificate2 msdn.microsoft.com/en-us/library/ms148413(v=vs.110).aspx - person pwdst; 16.11.2017
comment
В этом отношении MyType — это любой произвольный объект в том же проекте, что и ресурс, который может быть самим классом UnitTest, если вы храните сертификат в том же проекте. - person pwdst; 16.11.2017
comment
Примечание. YourProjectName должно быть пространством имен (в случае, если имя проекта и пространство имен отличаются). Используйте thisAssembly.GetManifestResourceNames() для проверки. - person heringer; 22.11.2017

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

Это было хорошо, когда: - Я знаю, что каждая машина, на которой выполняются эти тесты, имеет действительный сертификат. - Я использовал 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();
        }
    }
person Mike S    schedule 15.04.2014
comment
Это гениально для тестирования. Кстати, мы должны остерегаться паролей? - person Timo; 18.12.2015

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

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

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

Итак, что же такое «Кроты»?

«Moles — это упрощенная платформа для тестовых заглушек и обходных путей в .NET, основанная на делегатах. Moles можно использовать для обхода любого метода .NET, включая невиртуальные/статические методы в запечатанных типах. Moles находится в свободном доступе в галерее Visual Studio. или в комплекте с Pex».

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

person Cephron    schedule 28.07.2011
comment
Принял ответ Джейсона вместо моего, потому что он более общий. - person Cephron; 28.07.2011

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

  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");
person Ashwin    schedule 14.12.2016