안녕하세요,이 질문의 어떤 형태가 백만 가지 다른 방법으로 요청되었지만 많은 사람들이 답변을 얻지 못하거나 답변이 저에게 적용되지 않는 것 같습니다.
현재 TLS 1.2 만 지원하는 타사 API를 호출하는 사소한 .NET 서비스가 있습니다.
var requestHandler = new WebRequestHandler();
var clientCert = GetClientCert("THUMBPRINT");
requestHandler.ClientCertificates.Add(clientCert);
var encodedHeader = "FOO";
var httpClient = new HttpClient(requestHandler) { BaseAddress = new Uri("https://foo.bar.com/rest/api/") };
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedHeader);
var httpResponse = httpClient.GetAsync("").Result;
var responseContent = httpResponse.Content.ReadAsStringAsync().Result;
보안 프로토콜을 명시 적으로 1.2로 설정하거나 기본값이 1.2로 설정된 프레임 워크를 대상으로하면 클라이언트 인증서는 서버로가는 패킷의 일부가 아닙니다. Wireshark에서 조사했으며 인증서는 1.2 이상으로 존재하지 않습니다. 이 시점에서 서버는 Fatal Alert Handshake Failure (40)를 전송하여 다음과 같은 .Net 예외를 발생시킵니다.
The request was aborted: Could not create SSL/TLS secure channel.
Chrome 또는 Postman (기본)을 통해 동일한 전화를 걸 수 있으며 정상적으로 작동합니다. 프로토콜을 1.1로 설정하면 제대로 작동합니다. 그러나 .NET을 통해 1.2로 실행하면 매번 실패합니다. 의도적으로 클라이언트 인증서를 전혀 추가하지 않아도 Wireshark에서 동일한 오류와 동일한 트래픽이 발생합니다.
https://www.ssllabs.com/을 통해 타사 엔드 포인트를 실행했는데 등급이 괜찮습니다. 양쪽에서 볼 수있는 MD5 서명은 없습니다. 모든 것은 RSA 암호화를 사용하는 sha1 또는 sha256으로 서명됩니다.
추적을 활성화했습니다. 다음 출력은 인증서 또는 개인 키를 찾는 데 문제가 없음을 나타냅니다.
System.Net Information: 0 : [19512] SecureChannel#41622463 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [19512] SecureChannel#41622463::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Zero), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [19512] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Information: 0 : [19512] InitializeSecurityContext(credential =
System.Net.SafeFreeCredential_SECURITY, context = 1ed7465db80:1f1d854c910, targetName = foo.bar.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [19512] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=133, returned code=ContinueNeeded).
또한 SCHANNEL 이벤트 로깅이 켜져 있습니다. 개인 키로 클라이언트 인증서를 선택하는 것을 볼 수 있습니다.
The TLS client credential's private key has the following properties:
CSP name: Microsoft Enhanced Cryptographic Provider v1.0
CSP type: 1
Key name: {some hex here}
Key Type: key exchange
Key Flags: 0x0
The attached data contains the certificate.
Wireshark의 경고 패킷에 해당하는 오류가 이어집니다.
A fatal alert was received from the remote endpoint. The TLS protocol defined fatal alert code is 40.
나는 완전히 아이디어가 없습니다. .Net의 버그처럼 느껴집니다. 우리는 인증서 패키지에 클라이언트 인증서와 중간 CA 만 있기 때문에 클라이언트 인증서와의 불완전한 신뢰 체인이라고 잠시 생각했습니다. 그러나 우리는 공급 업체로부터 루트 CA를 얻었고 이제 Windows는 인증서가 합법적이라고 말합니다.
Wireshark에서 내가 주목 한 한 가지 흥미로운 점은 성공적인 호출에 대해 클라이언트 인증서와 중간 CA를 전송한다는 것입니다. 요청에 첨부하기 위해 클라이언트 인증서 만 가져 오기 때문에 중간 CA를 선택하는 방법을 모르겠습니다. 루트 CA가 있으면 왜 제출하지 않습니까? 내 직감은 문제가 여전히 여기 어딘가에있을 수 있지만 증명할 수 없다고 말합니다. 신뢰 체인 실패를 나타내는 로그는 어디에도 없습니다.
나는 심지어 ProcMon을 연결하여 잘못된 것을 볼 수 있지만 아무것도 튀어 나오지 않았는지 확인했습니다. 내가 이것에 소비 한 시간만큼 자바로 모든 것을 다시 작성할 수 있었다.
작동하지 않는 다른 몇 가지 시도 :
.Net 4.8 타겟팅
컴퓨터 저장소 대 사용자 저장소
대신 pfx에서 직접로드
HttpClient 대신 HttpWebRequest
SslStream을 사용하는 TcpClient
최신 Windows 10 릴리스
편집 나는 MD5와 함께 SHA-1 서명도 TLS 1.2에서 제거되었다는 것을 읽었습니다. 우리의 클라이언트 인증서는 SHA-1에 서명되었습니다. 나는 이것이 그것일지도 모른다고 생각하고 우리는 우리의 공급 업체에 연락하고있다.
내 문제와 내 해결책은 궁극적으로 이것과 같았습니다. 유일한 차이점은 내 클라이언트 인증서가 MD5가 아니라 SHA1이라는 것입니다. .NET은 SHA1 인증서도 분명히 삭제하고 있습니다.
C # 및 dotnet 4.7.1이 TLS 1.2 호출에 대한 사용자 지정 인증서를 추가하지 않음
다른 게시물에서 SHA1이 여전히 승인되었음을 표시했기 때문에이 기사에서 실마리를 얻었습니다. 내 SHA1 인증서는 여전히 .NET 외부에서 작동했습니다.
https://tools.ietf.org/id/draft-ietf-tls-md5-sha1-deprecate-00.html
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다