2017-12-20 18 views
18

사용자 지정 인증서로 https 호출을 생성하는 다음 C# 코드가 있습니다. Tls 1.1을 사용하면 호출이 정상적으로 작동합니다. Tls 1.2를 사용하면 호출이 중단됩니다. tls 1.2를 사용하여 컬을 사용하여 잘 작동합니다.C# 및 dotnet 4.7.1 TLS 1.2 호출 용 사용자 지정 인증서를 추가하지 않음

C# 코드 :

X509Certificate2Collection collection = new X509Certificate2Collection(); 
collection.Import("C:\\SomePath\\MyCertificate.pfx", "MyPassword", X509KeyStorageFlags.PersistKeySet); 
var cert = collection[0]; 

ServicePointManager.SecurityProtocol = ...; 

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => true; 
HttpClientHandler handler = new HttpClientHandler(); 
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true; 
handler.ClientCertificates.Add(cert); 

var content = new ByteArrayContent(Encoding.GetEncoding("latin1").GetBytes("Hello world")); 
HttpClient client = new HttpClient(handler); 
var resp = client.PostAsync(requestUri: url, content: content).Result.Content.ReadAsStringAsync().Result; 

작품으로 :

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11; 

오류와 :

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 

닷넷 오류 메시지 : SocketException이 : 기존의 연결이 강제로 폐쇄되었다 원격 호스트

.NET 버전 : 4.7.1

OS : 윈도우 10 버전 1,703 (지원되는 암호화 목록 : https://msdn.microsoft.com/en-us/library/windows/desktop/mt808163(v=vs.85).aspx) - 상기 서버는 지원되는 암호 사이 인 TLS_RSA_WITH_AES_256_GCM_SHA384 사용되도록 지정한다.

wireshark에서 저는 작업 호출 (C#/Tls 1.1 및 Curl Tls 1.2)에서 인증서가 서버로 전송되고 있음을 볼 수 있습니다. 다음은 C#을 TLS 1.1 전화에 대한 와이어 샤크 덤프입니다 :

Wireshark dump - Csharp tls 1.1

그러나, 또한 와이어 샤크에서, 나는 C#을 가진 것을 볼 수가/TLS 1.2에는 인증서가 클라이언트에서 서버로 전송되지되고있다.

enter image description here

사람이 내가 여기에 놓친 거지 무엇을 볼 수 있습니다 여기에 C#을 TLS 1.2 전화에 대한 와이어 샤크 덤프는?

UPDATE는

은 인증서가 TLS 1.2와 함께 창에서 샤넬에 의해 지원되지 않는 MD5 서명이 보인다. 우리의 벤더가 해결책으로 우리에게 또 다른 인증서를 만들었습니다. https://community.qualys.com/thread/15498

+0

.Net Core 2.0 클라이언트/서버 응용 프로그램과 비슷한 문제가 있습니다. 나는 서버에서 TLS 1.2를 강제로 해결했다. 이 방법은 클라이언트가 프로토콜과 인증서를 적절히 협상합니다. TLS 1.2 만 강제 실행되는 서버에 연결하려고 시도하고 .NET Framework에서 동일한 동작을하는지 확인하십시오. – Ghigo

+0

잘 서버를이 변경하는 것은 서버가 공급 업체에 속해 있기 때문에 실제로 여기 옵션이 아닙니다. 그리고 tls 1.1을 추가해도 상관 없습니다. tls 1.2가 허용 된 프로토콜 중 하나 인 경우이 문제가 발생합니다. 왜 곱슬 곱슬하게 잘 작동하는지 .net이 이런 식으로 행동하는지 알아야합니다. 그리고 정적 인 설정이고 다른 연결은 동일한 응용 프로그램의 tls 1.2에 의존하므로 tls 1.2를 활성화해야합니다. 이 한 번의 통화로 tls 1.3을 돌릴 수 있다면 그렇게 할 수 있습니다. 그러나 핸들러 객체에 프로토콜을 설정하면 현재 env에서 이것이 불가능하다는 것을 나타내는 예외가 발생합니다. –

+1

이 질문과 중복되는 것처럼 보입니다. https://stackoverflow.com/questions/44751179/tls-1-2-not-negotiated-in-net-4-7-without-explicit-servicepointmanager-security –

답변

0

이 코드는 항상 맹목적으로 진정한 반환하여 인증서 오류의 몇 가지 유형을 마스킹 믿습니다 :

난 당신이 기능을 가지고 추천

나는이 문제에 대해 설명이 임의의 스레드를 건너 왔어요 진정으로 arg4의 결과를 분석 할 수 있습니다. 이것이 귀하의 SSL 정책 오류입니다. 그들을 기록하면 답을 얻을 수 있습니다. 예제에서는 콘솔에 쓰지만 트레이스 나 파일에 쓸 수 있습니다. SslPolicyErrors 열거 형에 대한 값과 연관된 숫자가 생깁니다. 결과에 따라 체인 인 arg3을 확인해야 할 수도 있습니다.

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => { 

SslPolicyErrors errs = sslPolicyErrors; 
Console.WriteLine("Policy Errors " + sslPolicyErrors.ToString());   
return true;}; 
+0

우선, 논평 해 주셔서 감사합니다! 그러나 콜백 함수는 호출되지 않습니다. 방금 중단 점과 콘솔 쓰기 호출로 함수에 본문을 추가했는데이 중 아무 것도 히트를 치지 못했습니다. –

+0

Ctlsnkane 실제로 tls 1.2를 사용할 때 호출되지 않더라도 1.1을 사용할 때 실제로 호출되며 "System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors"오류 유형을 지정합니다. 이 메서드는 true를 반환하고 1.1에서 호출을 허용하지만 더 높은 보안 표준으로 인해이 호출을 허용하지 않습니다. 가장 좋은 건 왜 tls 1.1에서 체인 오류가 발생했는지 알아 내서 오류를 수정하고 tls 1.2로 다시 시도하는 것입니다. 나는 그 결과로 돌아갈 것이다. –

+0

콜백 메소드에 대해 입증 된 객체를 조금 파고 들자이 메시지를 자세히 살펴 보았습니다. "인증서 체인이 처리되었지만 트러스트 공급자가 트러스트하지 않은 루트 인증서에서 종료되었습니다." - 나는이 오류에 대해 특별히 google을 할 것이다. –

0

처리기의 SslProtocols 속성을 지정하지 않아야합니까?당신은이 문제의 근본 원인에 맞아

handler.SslProtocols = SslProtocols.Tls12; 
1

: 기본적으로 보안 채널 기반 클라이언트가 Win10/서버에서 SHA1, SHA256, SHA384 및 SHA512을 (제공 hander 정의 후이 줄을 추가

시도 2016). 따라서 TLS 1.2 서버는 MD5 인증서를 이러한 클라이언트에 보내지 않아야합니다.

클라이언트 (HttpClient)는 signature_algorithms 확장에 MD5를 나열하지 않으므로 TLS 1.2 핸드 셰이크가 실패합니다. 해결 방법은 보안 서버 인증서를 사용하는 것입니다.