C# HttpWebRequest 서버 인증서 확인

mohadang·2023년 1월 8일
0

C#

목록 보기
3/5
post-thumbnail

HttpWebRequest로 https 요청시 서버 인증서를 ServerCertificateValidationCallback로 확인 가능 하다.

var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "GET";
request.Timeout = _TimeOut;
request.ServerCertificateValidationCallback =
    (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
    {
        var publicKeyRawDatas = new List<byte[]>();        
        foreach (var chainElement in chain.ChainElements)
        {
            Console.WriteLine("ChainElements -------"); 
 			publicKeyRawDatas.Add(
            	chainElement.Certificate.PublicKey.EncodedKeyValue.RawData);
        }
        

        publicKeyRawDatas = new List<byte[]>();
        foreach (var chainElement in chain.ChainPolicy.ExtraStore)
        {
            Console.WriteLine("ExtraStore -------");
            publicKeyRawDatas.Add(chainElement.PublicKey.EncodedKeyValue.RawData);
        }

        return false;
    };

여기서 대부분 chain의 ChainElements에서 인증서를 가져올텐데 이는 문제를 발생 시킬 수 있다.

HttpWebRequest로 https 요청을 하기 위해 response API를 호출하면 서버에서는 응답으로 서버의 인증서를 전달한다.
이때 클라이언트에서 등록했던 ServerCertificateValidationCallback의 콜백이 호출되고 chain의 파라미터에 서버의 인증서, 이를를 싸인한 상위의 인증서 그리고 최종 ROOT CA 인증서 까지 chain으로 오게된다.

이때 윈도우 OS에 서버의 인증서가 이미 설치되어 있고 이 인증서를 싸인한 상위 인증서들이 같이 있으면 서버에서 주는 신선한 인증서 대신 기존 윈도우 OS에 설치된 인증서를 반환한다.
특히나 윈도우 OS에 설치된 서버의 인증서가 만료되고 이 서버를 싸인한 상위 또는 ROOT CA 인증서가 다르거나 만료 되어도 윈도우 OS의 인증서를 반환하는 경우가 있다.

이렇게 되면 서버에서 아무리 인증서를 갱신 해봤자 클라이언트에서는 서버에서 갱신한 인증서를 받을 수 없다.

이 문제를 해결하기 위해서 기존의 만료된 인증서를 제거하거나 직접 서버에서 갱신한 인증서를 설치하면 된다.
하지만 사용자 환경의 인증서를 조작하는건 별로 추천하지 않으며 ServerCertificateValidationCallback의 chain.ChainPolicy.ExtraStore에서 서버에서 전달하는 인증서를 확인할 수 있으니 이 속성도 고려하여 서버의 인증서를 검증하는 코드를 작성 해야한다.

profile
mohadang

0개의 댓글