Исключение при подключении SSL из службы Windows - PullRequest
0 голосов
/ 10 января 2012

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

class MyWebClient : WebClient
{
    public X509Certificate cert { set; get; }
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
        req.ClientCertificates.Clear();
        req.ClientCertificates.Add(cert);
        return req;
    }
}

Вот как я готовлю и делаю запросы:

try {
//...
string qry = "Some xml query...";
    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors) { return true; };

X509Certificate cert = X509Certificate.CreateFromCertFile(appPath + @"\data\cert.der");
MyWebClient cl = new MyWebClient();
cl.cert = cert;
string xmlReq = qry; 
cl.Headers[HttpRequestHeader.ContentType] = "text/xml";
var data = Encoding.UTF8.GetBytes(xmlReq);
byte[] res = cl.UploadData(apiUrl, data);
cl.Dispose();

string result = Encoding.UTF8.GetString(res);
} catch (Exception ex) {
//...
}
//...

Теперь я знаю, что загрузка сертификата из файла - не лучшая идея, но это не главное. Дело в том, что приведенный выше код прекрасно работает в настольном приложении, но выдает исключение «Не удалось установить безопасный канал для SSL / TLS» в службе Windows. Я попытался установить службу под учетной записью «localService» и «networkService», и это не делает никаких различий.

ОБНОВЛЕНИЕ: установка под "пользователем" также не помогла. Я что-то упустил?

1 Ответ

2 голосов
/ 10 января 2012

Когда вы загружаете сертификат с этим:

X509Certificate cert = X509Certificate.CreateFromCertFile(appPath + @"\data\cert.der");

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

После обсуждения в чате вы указали, что у вас также есть файл .p12 (PKCS # 12), .key и .pem, как и файл .der, который вы пытались нагрузки. Обычно эти расширения используются следующим образом:

  • .der для самого сертификата в кодировке DER (двоичный).
  • .pem для самого сертификата в кодировке PEM (base64-кодирование DER, с разделителями ---BEGIN....--- ... --- END ---).
  • .key для закрытого ключа.
  • .p12 (или .pfx) для файла PKCS # 12, который будет содержать как сертификат (и, возможно, цепочку CA), так и закрытый ключ.

В .Net база X509Certificate не позволит вам загрузить закрытый ключ вместе с сертификатом. Вы должны посмотреть на загрузку файла p12 в экземпляр X509Certificate2: по сути, это удобный класс, который не только моделирует сертификаты, но и может связывать закрытый ключ с объектом.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...