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

Пример SSLStream - как мне получить сертификаты, которые работают?

Я использую пример SSLStream из msdn здесь. Клиентский код "кажется" работает нормально, поскольку я могу подключиться к Google и, по крайней мере, пропустил проверку подлинности, но сервер этого не делает.

Из комментариев на странице msdn я использовал процедуру на этой странице, чтобы создать собственный закрытый ключ, но он просто не работает. Я получаю исключение из System.NotSupportedException: The server mode SSL must use a certificate with the associated private key.. Поэтому я уверен, что все, что я делаю, неверно.

Итак, мой вопрос прост: как мне получить/сгенерировать ключи, которые будут работать для моей небольшой примерной программы из msdn? Это может быть самозапись, независимо от того, но я слишком новичок в SSL, чтобы даже знать, что именно мне нужно. Все, что я хочу сделать, - запустить пример как заданный, за исключением указания моих собственных сертификатов для моего локального сервера. И было бы здорово узнать, что мне нужно будет установить на моей второй машине, если я просто хочу общаться между ними (так что это не 100% -ый пример localhost).

Лично я вижу это как недостаток в примере документа. Он должен сказать: "Чтобы запустить это, вам нужно сделать A, B, C и т.д.", Но это не так.

4b9b3361

Ответ 1

Вы можете заставить пример работать даже с самозаверяющими сертификатами. Я извлек команды из учебника makecert, которые вы используете с небольшими изменениями:

makecert -sv RootCATest.pvk -r -n "CN=FakeServerName" RootCATest.cer
makecert -ic RootCATest.cer -iv RootCATest.pvk -n "CN=FakeServerName" -sv  TempCert.pvk -pe -sky exchange TempCert.cer
cert2spc TempCert.cer TempCert.spc
pvkimprt -pfx TempCert.spc TempCert.pvk

makecert и cert2psc можно найти в папке Microsoft SDKs\Window\v7.0A\Bin. Установщик pvkImport.exe можно скачать здесь (предоставлено @Jospeph и VirusTotal подтверждено). Это использовалось для загрузки с сайта Microsoft, но с тех пор они сняли его.

Для этого следующего шага убедитесь, что вы выбрали ЭКСПОРТ закрытого ключа при появлении диалога из pvkimprt:

pvkimprt -pfx TempCert.spc TempCert.pvk

enter image description here

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

enter image description here

Затем импортируйте RootCATest.cer в хранилище доверенных корневых центров сертификации Computer (как на сервере, так и на клиенте). Обратите внимание, что сертификат выдается FakeServerName. Это должно совпадать с именем сервера, которое ожидает SslTcpClient: sslStream.AuthenticateAsClient(serverName), где serverName - это значение второго аргумента, переданного SslTcpClient.exe.

Когда ваш клиент подключается, сервер представляет сертификат, который сообщает клиенту "I'm FakeServerName". Клиент принимает это требование, если клиентская машина доверяет ЦС, выдавшему сертификат, который достигается путем импорта RootCATest.cer в доверенные доверенные корневые центры клиентов.

Наконец, вам нужно импортировать закрытый ключ, который сервер будет использовать в личном хранилище сервера. Этот шаг важен, поскольку он адресует The server mode SSL must use a certificate with the associated private key.. Это достигается за счет импорта файла .pfx, который вы создали ранее. Убедитесь, что вы изменили фильтр типа файла на "все файлы", чтобы вы могли увидеть файл .pfx, который вы создали:

enter image description here

Пример кода, предоставленного MSDN, использует порт 443 (который является стандартным портом ssl). Поскольку я создал консольные приложения, я изменил порт, используемый классами образцов, на 8080:

SslTcpServer:

TcpListener listener = new TcpListener(IPAddress.Any, 8080);

SslTcpClient:

TcpClient client = new TcpClient(machineName, 8080);

Здесь вывод:

enter image description here

вы запустили бы свой сервер следующим образом:

SslTcpServer.exe TempCert.cer 

от клиента, вы должны подключиться следующим образом:

SslTcpClient.exe <ip to your server> FakeServerName

Ответ 2

сгенерируйте сертификат, используя следующую команду:

makecert -r -pe -n "CN=localhost" -m 12 -sky CertSubject -ss my serverCert.cer

а затем от клиента подключиться к серверу, как это (предполагая, что мы используем пример MSDN, который вы упомянули):

SslTcpClient.RunClient ("localhost", "CertSubject");

вы получите ошибки проверки в вызове ValidateServerCertificate(), но это ожидается - вы используете самозаверяющий сертификат. Просто вернитесь туда.

UPDATE:

Я не согласен с предложением Тунга о добавлении самозаверяющего сертификата в клиентские доверенные корневые центры сертификации. Я думаю, что это может вызвать проблемы позже, если вы планируете распространять/поддерживать свое программное обеспечение. Например, клиент может переустанавливать окна или перемещать свой профиль на другой компьютер или что-то в этом роде - и понимая, ПОЧЕМУ ваше программное обеспечение внезапно перестало работать, будет боль (опять же, я говорю долговременно - через год или два, когда вы полностью забываете этот маленький "трюк" ).

Вместо этого я предпочел бы "жестко закодировать" ваш сертификат (путем сравнения темы и отпечатка пальца) в логике клиента, что-то вроде этого:

X509Certificate2 certificate = (X509Certificate2)cert;
if (certificate.Subject.StartsWith("CN=FAKE_SERVER_WHATEVER") &&
    !string.IsNullOrEmpty(certificate.Thumbprint) &&
    certificate.Thumbprint.ToLower() == "11c4446c572a9918ced3618728b91b3a07982787")
{
     return true;
}
return false;

Ответ 3

Поскольку ссылка Microsoft для загрузки pvkimprt нарушена, и я являюсь поклонником OpenSSL, здесь я оставляю два решения с OpenSSL.

VARIANT # 1 - Самоподписанный сертификат

Сначала вам понадобится загрузить OpenSSL и эту конфигурацию file. @Tung сказал, что вы можете использовать совершенно самозаверяющий сертификат. Скопируйте загруженный файл конфигурации в ту же папку, в которой будут выполняться команды OpenSSL.

Позволяет создать закрытый ключ и сертификат Центра сертификации:

openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -out ssl-cacert.pem -keyout ssl-cakey.pem -outform PEM

* Используйте параметр -nodes, чтобы опустить кодовую фразу, но по соображениям безопасности лично я не рекомендую его.

Если вы хотите проверить информацию о сертификате CA, выполните следующую команду:

openssl x509 -purpose -in ssl-cacert.pem -inform PEM

Позволяет создать запрос сертификата, Общее имя должно быть указано с именем машины:

openssl req -config openssl.cnf -newkey rsa:2048 -keyout ssl-serverkey.pem -sha256 -out ssl-server.csr -outform PEM

* То же замечание для параметра -nodes.

Если вы хотите проверить информацию о запросе сертификата, выполните команду:

openssl req -text -noout -verify -in ssl-server.csr

Подпишите запрос сертификата сгенерированным сертификатом ЦС:

openssl x509 -req -days 365 -CA ssl-cacert.pem -CAkey ssl-cakey.pem -CAcreateserial -in ssl-server.csr -out ssl-server-certificate.pem

Позволяет сделать самозаверяющий сертификат с форматом PFX:

openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-server-certificate.pem -certfile ssl-cacert.pem -name "SSL Self Signed Certificate"

Теперь вы должны импортировать сертификат .pfx.

  • Дважды щелкните файл ssl-certificate.pfx.
  • Выберите опцию "Локальный компьютер" и "Далее".
  • Введите пароль и установите флажок . Отметьте этот ключ как экспортируемый.
  • Выберите переключатель "Поместите все сертификаты в следующее хранилище" .
  • Выберите Персональный магазин и нажмите "Далее".

Эти шаги должны работать.

VARIANT # 2 - сформировать сертификат ЦС и сертификат сервера

Лично я предпочитаю это решение по первому, потому что только я должен распространять сертификат корневого ЦС для клиентов.

Сначала загрузите этот конфигурационный файл.

Мы сгенерируем сертификат Root CA с соответствующим закрытым ключом:

openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -keyout ssl-cakey.pem -out ssl-cacert.pem -outform PEM

Позволяет проверить свойства сертификата:

openssl x509 -purpose -in ssl-cacert.pem -inform PEM

Информация, которая должна отображаться, должна выглядеть следующим образом:

Certificate purposes:
SSL client : No
SSL client CA : Yes
SSL server : No
SSL server CA : Yes
Netscape SSL server : No
Netscape SSL server CA : Yes
S/MIME signing : No
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : Yes
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
-----BEGIN CERTIFICATE-----
MIIGLjCCBBagAwIBAgIJANCzs7UBFJMpMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
...
im1yDnB5nPwkPwZ9eRmlzIc6OaLZcfbFfSeSw8/ipKZcEJ1u+EFrB0JhuSbeLXtQ
N/8=
-----END CERTIFICATE-----

Создайте запрос сертификата с помощью следующей команды:

openssl req -config openssl.cnf -newkey rsa:2048 -sha256 -keyout ssl-serverkey.pem -out ssl-servercert.csr -outform PEM

Очень важно установить общее имя с именем компьютера сервера.

Проверьте информацию этого запроса сертификата:

openssl req -text -noout -verify -in ssl-servercert.csr

Отображение информации должно иметь следующий формат, убедитесь, что поле CN в разделе Subject является именем серверной машины.

verify OK
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=US, ST=..., L=..., O=..., OU=..., CN=SERVERNAME
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:aa:92:bd:87:75:18:6c:c0:23:3f:0b:5a:46:1a:
                    ...
                    fe:13
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Key Identifier:
                7E:7D:79:F4:CD:71:0E:90:3A:9A:F8:3F:83:7D:89:90:4D:D4:F0:12
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment, Data Encipherment
    Signature Algorithm: sha256WithRSAEncryption
         34:e1:b4:db:b2:87:cc:11:3e:85:3c:ed:ac:8d:d9:43:ae:b0:
         ...
         56:84:29:f9

Создайте папку сертификатов:

mkdir certificates

Создайте индексный файл базы данных:

Windows: type NUL > index.txt
  Unix: touch index.txt

Создайте файл serial.txt, где хранится текущий серийный номер:

echo '01' > serial.txt

Создайте сертификат сервера, который подписывает запрос на сертификат в течение 2 лет с помощью команды. Вам будет предложено передать фразу сертификата CA в зависимости от параметра -nodes:

openssl ca -config openssl.cnf -days 730 -policy signing_policy -extensions v3_req -out ssl-servercert.pem -infiles ssl-servercert.csr

Затем отображается текст с форматом:

Check that the request matches the signature
Signature ok
The Subject Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :ASN.1 12:'...'
localityName          :ASN.1 12:'...'
organizationName      :ASN.1 12:'...'
organizationalUnitName:ASN.1 12:'...'
commonName            :ASN.1 12:'SERVERNAME'
Certificate is to be certified until Jul  4 23:26:59 2018 GMT (730 days)
Sign the certificate? [y/n]: 

Выберите y и предложит следующий текст, выберите y еще раз:

1 out of 1 certificate requests certified, commit? [y/n]

Экспорт сгенерированного сертификата в формат PFX:

openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-servercert.pem -name "SSL Signed Certificate"

Вам понадобится выполнить следующие шаги, чтобы включить SSL без проблем:

На серверной машине:

  • Импортировать сертификат корневого ЦС (файл ssl-cacert.pem) в хранилище доверенных корневых центров сертификации, выбрав "Компьютерная учетная запись".
  • Импортировать сертификат сервера для SSL (файл ssl-certificate.pfx) в личном хранилище, выбрав учетную запись компьютера.

На клиентских машинах:

  • На каждом клиентском компьютере вам потребуется импортировать корневой сертификат CA (файл ssl-cacert.pem) в хранилище доверенных корневых центров сертификации, выбрав "Компьютерная учетная запись".

Не стесняйтесь вносить какие-либо изменения или предложения.