Страница 1 из 1

Подключение к серверу с SSL сертификатами

Добавлено: 13 июл 2015, 17:56
Mad!sson
Добрый день, мужчины!
Вот такая проблема. Есть сервер к которому нужно подключится. Сервер для защиты использует SSL сертификаты. По задаче нужно отправить запрос на сервер и получить от него ответ. Сертификаты на руках и уже установлены в хранилище сертификатов. Отправляемый контент содержит "подпись" которая так-же получается с помощью ключей, находящихся в этих сертификатах. Подпись правильная и проверена владельцами сервера, по этому исключаю ошибку в ней. Итого имеем: сертификат CA certificate file.cer, client certificate file.pfx, private key file.pfx и пароль (все предоставил владелец сервера). Козалось все просто, есть все составляющие осталось только написать код.

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

Решил воспользоватся примером владельца написанным на С#. Для этого использовал следующий код:

private string Sign(string data)
{
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certColl = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateSign, false);
var cert = certColl[0];
var rsa = (RSACryptoServiceProvider)cert.PrivateKey;
var signature = rsa.SignData(Encoding.UTF8.GetBytes(data), new SHA1CryptoServiceProvider());
return Utilities.BytesToHex(signature);
}
private void VerifySign(string data, string signature)
{
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certColl = store.Certificates.Find(X509FindType.FindBySubjectName, "private", false);
var cert = certColl[0];
var pubKey = (RSACryptoServiceProvider)cert.PublicKey.Key;

var isValid = pubKey.VerifyData(Encoding.UTF8.GetBytes(data), new SHA1CryptoServiceProvider(), Utilities.HexToBytes(signature));
if (!isValid)
throw new Exception("Invalid Signature");
}
private static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[1024];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public static bool TrustAllCertificateCallback(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
return true;
}
public string ExecutePOST(string content)
{
var httpRequest = (HttpWebRequest)HttpWebRequest.Create(GatewayUrl);
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certColl = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateClient, false);
httpRequest.ClientCertificates.Add(certColl[0]);
httpRequest.Method = "POST";
httpRequest.Accept = "*/*";
ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificateCallback;

byte[] requestBuff = Encoding.UTF8.GetBytes(content);
using (var requestStream = httpRequest.GetRequestStream())
{
requestStream.Write(requestBuff, 0, requestBuff.Length);
requestStream.Flush();
}
var response = (HttpWebResponse)httpRequest.GetResponse();
var responseBuff = ReadFully(response.GetResponseStream());
if (response.ContentEncoding.ToLower().Contains("gzip"))
responseBuff = new CompressProvider().Decompress(responseBuff);
return Encoding.UTF8.GetString(responseBuff);

Реализация его в Лабвью на картинке 3 и 4.

Но сдесь тоже есть проблема. Не могу реализовать следующюю строчку, а именно указать УРЛ по которому нужно отправить запрос:
var httpRequest = (HttpWebRequest)HttpWebRequest.Create(GatewayUrl);
Дело в том, что метод Create(GatewayUrl) принадлежит классу WebRequest, который не доступен для меня (картинка 4). На МСДН предлагаютт альтернативнуюю библиотеку, но там этот класс тоже не доступен.

В общем помогите кто как может!!:)

Re: Подключение к серверу с SSL сертификатами

Добавлено: 13 июл 2015, 18:19
dadreamer
Mad!sson писал(а):Не могу реализовать следующюю строчку, а именно указать УРЛ по которому нужно отправить запрос:
var httpRequest = (HttpWebRequest)HttpWebRequest.Create(GatewayUrl);
Посмотрите здесь, не это ли требуется?

Re: Подключение к серверу с SSL сертификатами

Добавлено: 13 июл 2015, 18:29
Mad!sson
Да, это оно! Но как?

Re: Подключение к серверу с SSL сертификатами

Добавлено: 13 июл 2015, 18:46
dadreamer
Mad!sson, кидаете на панель пустой .NET контейнер, на БД заменяете его на константу. Потом ПКМ на ней -> Select .NET Class -> Browse. В появившемся окне выбираете сборку System (2.0.0.0), в нижнем поле раскрываете объект System.Net и наконец выбираете WebRequest.

Re: Подключение к серверу с SSL сертификатами

Добавлено: 14 июл 2015, 09:42
Mad!sson
Спасибо за помощь. А вы не знаете, что не так с первым вариантом? Может быть, что в коде Сшарп сертификаты достаются с хранилища, а в обычном запросе просто указывается путь к файлам сертификатов?

Re: Подключение к серверу с SSL сертификатами

Добавлено: 14 июл 2015, 12:02
dadreamer
Mad!sson, затрудняюсь сказать насчёт собственных сертификатов. Насколько я знаю, если сертификат нормально подхватывается в обычном браузере, то в среде программирования дополнительно ничего делать не нужно. Вот в качестве примера авторизация на Mail.Ru:
2015-07-14_13-54-37.jpg
2015-07-14_13-50-24.jpg
Mail.Ru.vi
lv2013
(16.1 КБ) 209 скачиваний
Так что, по идее, если сертификаты уже в хранилище и через браузер всё ОК, то в :labview: достаточно заполнить вышеуказанные заголовки и отправить POST-запрос.

Re: Подключение к серверу с SSL сертификатами

Добавлено: 14 июл 2015, 12:21
Mad!sson
Да нет. Так не получается. Выдает ошибку 403 в браузере. Говорит, не хватает прав.

Вот еще маленький вопрос. В строке
public static bool TrustAllCertificateCallback(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) не могу понять что за object sender и откуда его брать. Может у вас есть какие-либо мысли? Нашел некий некий класс System.Object, который указывает Visual Studio, но при выполнении всей функции выдает ошибку: Ключь не может быть неопределенным.
TrustAllCertificateCallback(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificateCallback;

Re: Подключение к серверу с SSL сертификатами

Добавлено: 14 июл 2015, 13:01
dadreamer
Mad!sson писал(а):Да нет. Так не получается. Выдает ошибку 403 в браузере. Говорит, не хватает прав.
Значит, чего-то недокрутили. В большинстве случаев удобнее сначала реализовать обмен в браузере, создав простенькую HTML-форму, или используя сниффер и сайт сервера. Если у вас нет ни того, ни другого, то остается только копаться в IDE. :dntknw:
Mad!sson писал(а):не могу понять что за object sender и откуда его брать
Ну, очевидно, что это объект (контрол), вызывающий событие - функцию TrustAllCertificateCallback. Как например, для события OnClick вызывающим объектом (sender) будет кнопка. Если это callback-функция, то она в таком виде, как на картинке, не может вызываться. Скорее всего, её нужно реализовать отдельно в библиотеке и подключать по ссылке. Большего сказать не могу. Посмотрите ещё здесь и почитайте документацию от производителя.

Re: Подключение к серверу с SSL сертификатами

Добавлено: 15 июл 2015, 10:11
Mad!sson
В общем проблема решена. Пришлось отказатся от этой части кода. Хотя она для отправки и не нужна. Вот :vi: для запроса на сервер с SSL сертфикатами. Так же в ней реализовано распаковка gzip архива, вслучае если ответ от сервера запакован. Также есть :vi: с шифровкой запроса через PrivetKey. Я использую ее для шифрования подписи.
Все :vi: были составлены с помощью библиотек System.llb 2.0.0.0 и mscorlib.llb 2.0.0.0