Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

  • Создайте сертификат, используя makecert.
  • Добавьте сертификат в свой проект и измените его действие Build на встроенный ресурс.
  • Загрузите сертификат из ресурса в настройке unit test, см. ниже.

код:

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

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

Ответ 2

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

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

Ответ 3

В запросе Langdon я использовал решение:

        //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 для этих полей, чтобы вернуть фиктивные строки. Если бы вы получили доступ к другим полям, вам, вероятно, нужно было бы их ролить.

Итак, что такое "Moles"?

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

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

Ответ 4

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

  • Создайте сертификат с помощью MakeCert или экспортируйте любой существующий сертификат.
  • Добавить сертификат в папку Project (папка App_Data).
  • Следуйте инструкциям ниже, чтобы получить сертификат.

Код:

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