LoginSignup
1
5

More than 1 year has passed since last update.

C#の証明書読み込み

Last updated at Posted at 2022-04-17

はじめに

HttpClientでクライアント証明書を使うとか、証明書を.NETのプログラムで読み込む話。

証明書ストアからの読み込み

System.Security.Cryptography.X509CertificatesのX509Storeを使うと、証明書ストアから読み込みできる。
例えば、個人証明書を読み込む場合は以下のようになる。


using System;
using System.Security.Cryptography.X509Certificates;

namespace clientcert
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 証明書ストアの現在のユーザ(Windowsアカウント)の「個人」を開く
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            // 証明書を選ぶ(絞り込む)、まずは有効期間内のもの
            // 最後のtrueは証明のパスが正式なもののみ取り出す指定なので、オレオレの場合はfalseにする
            X509Certificate2Collection col_all = store.Certificates;
            X509Certificate2Collection col_date = col_all.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
            // 次に署名者の名前(CA証明書のCNなど)で絞り込む
            X509Certificate2Collection col_issuer = col_date.Find(X509FindType.FindByIssuerName, "TestRoot", true);

            // 見つかった証明書を出力
            // X509Certificate2のオブジェクトなので、HttpClientとかでクライアント証明書として使える
            foreach (X509Certificate2 cert in col_issuer)
            {
                Console.WriteLine(cert.ToString());
            }
        }
    }
}

cert.Issuer は普通に文字列なので、Findで絞らず、自分で文字列を比較するなどでも問題ない。
オレオレ証明書で、ルート証明書をインポートしていない場合、Findの最後の引数をfalseにしないと出てこなくなるので注意。

ファイルからの読み込み

証明書ストアに入れないで読み込む場合、また、Windowsサービスから使うなど、ユーザが異なる場合はファイルから読み込むこともできる。
一般的にはpkcs12ファイル(.p12, .pfx)だと思うので、その想定。

using System;
using System.Security.Cryptography.X509Certificates;
using System.IO;

namespace clientcert
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // ファイルをバイト列として読み込む
            // ファイル全体を読んで、全部読めなかったら(ファイルサイズと読み込んだサイズが違ったら)エラーにしている
            byte[] file_data = null;
            try
            {
                // 証明書のファイル名はここで指定
                using (FileStream fs = new FileStream("client01.pfx", FileMode.Open, FileAccess.Read))
                {
                    file_data = new byte[fs.Length];
                    int read_size = fs.Read(file_data, 0, file_data.Length);
                    if (read_size != fs.Length)
                    {
                        Console.WriteLine("Read error: size=" + read_size);
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return;
            }

            // クライアント証明書のパスワード
            string cert_pass = "password";

            // ここまで来たらX509Certificate2のインスタンスが作れる
            X509Certificate2 cert2 = new X509Certificate2(file_data, cert_pass, X509KeyStorageFlags.EphemeralKeySet);
            Console.WriteLine(cert2.ToString());
        }
    }
}

使い方によっては X509KeyStorageFlags.EphemeralKeySetのところを変える必要があるかもしれない。

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5