Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

背景

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

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

プログラム

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

https://github.com/ShTair/CertificatesChecker/blob/master/CertificatesChecker/CertificateManager.cs

public static async Task<X509Certificate2> GetCertificateAsync(string uri)
{
    var tcs = new TaskCompletionSource<X509Certificate2>();
    _ = Task.Run(async () =>
    {
        var handler = new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (_1, c, _2, _3) =>
            {
                tcs.TrySetResult(new X509Certificate2(c.RawData));
                return false;
            },
        };

        try
        {
            using (var hc = new HttpClient(handler))
            {
                await hc.GetAsync(uri);
            }
        }
        catch (Exception exp)
        {
            tcs.TrySetException(exp);
        }
    });

    return await tcs.Task;
}

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

使い方

using (var certificate = await GetCertificateAsync("https://qiita.com/"))
{
    Console.WriteLine($"[{certificate.NotBefore:yyyy/MM/dd HH:mm:ss}]から[{certificate.NotAfter:yyyy/MM/dd HH:mm:ss}]まで有効");
}
ShTair
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away