Quantcast
Viewing all articles
Browse latest Browse all 8895

任意のサイトのSSLサーバ証明書を取得する

背景

Let's Encryptの証明書は90日で期限が切れちゃうので、定期的に期限を確認して、切れそうだったら教えてくれるプログラムを作りたいと思った。

しかし、いまいちC#でサーバ証明書を取得する正しい方法がわからない…
思いついた方法で無理やり作ったので、知っている人いたら教えてください。

プログラム

HttpClientは、内部でSSLサーバ証明書を取得していて、有効かどうかを判定している。
HttpClientHandlerServerCertificateCustomValidationCallbackを指定すると、証明書が有効かどうかの判定を上書きできる。
その時に証明書にアクセスできるので、それを取り出せば、めでたくサーバ証明書を取得できる。

publicstaticasyncTask<X509Certificate2>GetCertificateAsync(stringuri){vartcs=newTaskCompletionSource<X509Certificate2>();_=Task.Run(async()=>{varhandler=newHttpClientHandler{ServerCertificateCustomValidationCallback=(_1,c,_2,_3)=>{tcs.TrySetResult(newX509Certificate2(c.RawData));returnfalse;},};try{using(varhc=newHttpClient(handler)){awaithc.GetAsync(uri);}}catch(Exceptionexp){tcs.TrySetException(exp);}});returnawaittcs.Task;}

ServerCertificateCustomValidationCallbackで証明書にアクセスできるが、その証明書はすぐに破棄されてしまうようなので、RawDataを使って証明書を複製している。WEBページの内容を取得したいわけじゃないので、false(証明書が無効であること)を返して、内容を取得しないことを期待している。

使い方

using(varcertificate=awaitGetCertificateAsync("https://qiita.com/")){Console.WriteLine($"[{certificate.NotBefore:yyyy/MM/ddHH:mm:ss}]から[{certificate.NotAfter:yyyy/MM/ddHH:mm:ss}]まで有効");}

Viewing all articles
Browse latest Browse all 8895

Trending Articles