답변:
Windows 8.1에서는 이제 잘못된 SSL 인증서를 신뢰할 수 있습니다. Windows.Web.HttpClient를 사용하거나 System.Net.Http.HttpClient를 사용하려면 내가 작성한 메시지 처리기 어댑터를 사용할 수 있습니다. http://www.nuget.org/packages/WinRtHttpClientHandler
문서는 GitHub에 있습니다 : https://github.com/onovotny/WinRtHttpClientHandler
빠르고 더러운 해결책은 ServicePointManager.ServerCertificateValidationCallback
대리자 를 사용하는 것 입니다. 이를 통해 자체 인증서 유효성 검사를 제공 할 수 있습니다. 유효성 검사는 전체 앱 도메인에 전역 적으로 적용됩니다.
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
주로 호스팅중인 엔드 포인트에 대해 실행하고 WCF 클라이언트 또는 HttpClient
.
프로덕션 코드의 경우 더 세밀한 제어를 원할 수 있으며 WebRequestHandler
및 ServerCertificateValidationCallback
대리자 속성을 사용하는 것이 좋습니다 (아래 dtb의 답변 참조 ). 또는 ctacke의 대답은 를 사용하여 HttpClientHandler
. 다른 후크를 찾을 수없는 경우를 제외하고는 이전 방식보다 통합 테스트에서도이 두 가지 중 하나를 선호합니다.
WebRequestHandler 클래스 와 해당 ServerCertificateValidationCallback 속성을 살펴보십시오 .
using (var handler = new WebRequestHandler())
{
handler.ServerCertificateValidationCallback = ...
using (var client = new HttpClient(handler))
{
...
}
}
derived class
?
HttpClientHandler
?
.NET Standard 라이브러리에서이 작업을 수행하려는 경우 true
처리기에서 반환하는 모든 위험이있는 간단한 솔루션 이 있습니다. 나는 당신에게 안전을 맡깁니다.
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
};
var client = new HttpClient(handler);
또는 네임 스페이스 에서 HttpClient 에 사용할 수 있습니다 Windows.Web.Http
.
var filter = new HttpBaseProtocolFilter();
#if DEBUG
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
#endif
using (var httpClient = new HttpClient(filter)) {
...
}
System.Net.Http
, System.Web
과 Windows.Web.Http
함께?
사용하는 경우 System.Net.Http.HttpClient
올바른 패턴이
var handler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
var http = new HttpClient(handler);
var res = http.GetAsync(url);
여기에서 대부분의 답변은 일반적인 패턴을 사용하도록 제안합니다.
using (var httpClient = new HttpClient())
{
// do something
}
IDisposable 인터페이스 때문입니다. 제발 하지마!
Microsoft는 다음과 같은 이유를 알려줍니다.
그리고 여기서이면에서 일어나는 일에 대한 자세한 분석을 찾을 수 있습니다. https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
SSL 질문과 관련하여 https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem을 기반으로합니다.
패턴은 다음과 같습니다.
class HttpInterface
{
// https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
// https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient#remarks
private static readonly HttpClient client;
// static initialize
static HttpInterface()
{
// choose one of these depending on your framework
// HttpClientHandler is an HttpMessageHandler with a common set of properties
var handler = new HttpClientHandler();
{
ServerCertificateCustomValidationCallback = delegate { return true; },
};
// derives from HttpClientHandler but adds properties that generally only are available on full .NET
var handler = new WebRequestHandler()
{
ServerCertificateValidationCallback = delegate { return true; },
ServerCertificateCustomValidationCallback = delegate { return true; },
};
client = new HttpClient(handler);
}
.....
// in your code use the static client to do your stuff
var jsonEncoded = new StringContent(someJsonString, Encoding.UTF8, "application/json");
// here in sync
using (HttpResponseMessage resultMsg = client.PostAsync(someRequestUrl, jsonEncoded).Result)
{
using (HttpContent respContent = resultMsg.Content)
{
return respContent.ReadAsStringAsync().Result;
}
}
}
Windows 런타임 애플리케이션 용인 경우 자체 서명 된 인증서를 프로젝트에 추가하고 appxmanifest에서 참조해야합니다.
문서는 여기에 있습니다 : http://msdn.microsoft.com/en-us/library/windows/apps/hh465031.aspx
신뢰할 수없는 CA (예 : 머신 자체가 신뢰하지 않는 사설 CA)에서 가져온 경우도 마찬가지입니다. CA의 공용 인증서를 가져 와서 앱에 콘텐츠로 추가 한 다음 매니페스트에 추가해야합니다.
완료되면 앱에서 올바르게 서명 된 인증서로 표시됩니다.
답은 없지만 대안이 있습니다.
Fiddler2 를 사용 하여 트래픽을 모니터링하고 HTTPS 복호화를 활성화하면 개발 환경이 불평하지 않습니다. 표준 앱을 설치할 수 없기 때문에 Microsoft Surface와 같은 WinRT 장치에서는 작동하지 않습니다. 그러나 개발 Win8 컴퓨터는 괜찮습니다.
Fiddler2에서 HTTPS 암호화를 활성화하려면 도구> Fiddler 옵션> HTTPS (Tab) 로 이동하여 "HTTPS 트래픽 해독"을 선택합니다. 합니다.
누군가가 우아한 해결책을 갖기를 바라면서이 스레드를 계속 주시 할 것입니다.
이 Kubernetes 클라이언트 에서 X509VerificationFlags.AllowUnknownCertificateAuthority 를 사용하여 자체 서명 된 자체 서명 된 루트 인증서를 신뢰 하는 예제를 찾았습니다 . 나는 우리 자신의 PEM 인코딩 루트 인증서로 작업하기 위해 그들의 예제를 약간 수정했습니다. 바라건대 이것은 누군가를 도울 것입니다.
namespace Utils
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
/// <summary>
/// Verifies that specific self signed root certificates are trusted.
/// </summary>
public class HttpClientHandler : System.Net.Http.HttpClientHandler
{
/// <summary>
/// Initializes a new instance of the <see cref="HttpClientHandler"/> class.
/// </summary>
/// <param name="pemRootCerts">The PEM encoded root certificates to trust.</param>
public HttpClientHandler(IEnumerable<string> pemRootCerts)
{
foreach (var pemRootCert in pemRootCerts)
{
var text = pemRootCert.Trim();
text = text.Replace("-----BEGIN CERTIFICATE-----", string.Empty);
text = text.Replace("-----END CERTIFICATE-----", string.Empty);
this.rootCerts.Add(new X509Certificate2(Convert.FromBase64String(text)));
}
this.ServerCertificateCustomValidationCallback = this.VerifyServerCertificate;
}
private bool VerifyServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
// add all your extra certificate chain
foreach (var rootCert in this.rootCerts)
{
chain.ChainPolicy.ExtraStore.Add(rootCert);
}
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
var isValid = chain.Build((X509Certificate2)certificate);
var rootCertActual = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
var rootCertExpected = this.rootCerts[this.rootCerts.Count - 1];
isValid = isValid && rootCertActual.RawData.SequenceEqual(rootCertExpected.RawData);
return isValid;
}
// In all other cases, return false.
return false;
}
private readonly IList<X509Certificate2> rootCerts = new List<X509Certificate2>();
}
}
온라인에서 잘 작동하는 예를 찾았습니다.
먼저 새 ICertificatePolicy 를 만듭니다.
using System.Security.Cryptography.X509Certificates;
using System.Net;
public class MyPolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request,
int certificateProblem)
{
//Return True to force the certificate to be accepted.
return true;
}
}
그런 다음 http 요청을 보내기 전에 다음과 같이 사용하십시오.
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/
ServicePointManager.CertificatePolicy
더 이상 사용되지 않음 : docs.microsoft.com/en-us/dotnet/framework/whats-new/…