C#で証明書ファイル(CRTファイル)とキーファイル(KEYファイル)を読み込む場合、OpenSSLなどを利用して、P12ファイルに変換する必要があります。
システムエンジニアでは無い、一般の人にはP12ファイルへの変換は抵抗感を感じてしまいます。
ですので、以前からC#で直接CRTファイルとKEYファイルを読み込めないか?考えていましたが、最近方法を見つけたので記事にしてみました。
使用した開発環境はVisual Studio Community 2019 になります。
NuGetで「BouncyCastle」を追加する
プロジェクトを開いて、「ツール」→「NuGetパッケージマネージャー」→「ソリューションのNuGetパッケージの管理」を開きます。
参照タブを開いて検索窓に「BouncyCastle」と入力し、「BouncyCastle」を選択してインストールします。
CRTファイルとKEYファイル読み込みサンプル
Yahooショッピングの注文APIサンプルでも作成しようかとも思いましたが、なるべくシンプルにしました。
作成したフォームはこんな感じです。
フォームクラスに、public変数「cert」を宣言し、読み込んだCRTファイルとKEYファイルでP12形式の値にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; //ファイル存在チェックで利用 using System.IO; //証明書関連 using System.Security.Cryptography.X509Certificates; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; namespace ssl { public partial class Form1 : Form { //証明書 public System.Security.Cryptography.X509Certificates.X509Certificate2 cert = null; public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { var dia = new OpenFileDialog(); dia.Multiselect = false; dia.Filter = "crtファイル(*.crt)|*.crt"; if (dia.ShowDialog() == DialogResult.OK) { textBox1.Text = dia.FileName; } } private void button3_Click(object sender, EventArgs e) { var dia = new OpenFileDialog(); dia.Multiselect = false; dia.Filter = "keyファイル(*.key)|*.key"; if (dia.ShowDialog() == DialogResult.OK) { textBox2.Text = dia.FileName; } } private void button1_Click(object sender, EventArgs e) { if (SetCertFile(textBox1.Text, textBox2.Text)) { MessageBox.Show("証明書ファイルの読み込みが完了しました。", "正常終了", MessageBoxButtons.OK, MessageBoxIcon.Information); } } public bool SetCertFile(string strCertFile, string strKeyFile) { //ファイル存在チェック if (!System.IO.File.Exists(strCertFile) || !System.IO.File.Exists(strKeyFile)) { return false; } //パスワード作成 Guid g = System.Guid.NewGuid(); string pass = g.ToString("N").Substring(0, 8); AsymmetricCipherKeyPair privateKey; Org.BouncyCastle.X509.X509Certificate readedCert; // 秘密鍵の読み込み using (var reader = new StreamReader(strKeyFile, Encoding.ASCII)) { var pemReader = new PemReader(reader); privateKey = (AsymmetricCipherKeyPair)pemReader.ReadObject(); } // 証明書の読み込み using (var reader = new StreamReader(strCertFile, Encoding.ASCII)) { var pemReader = new PemReader(reader); readedCert = (Org.BouncyCastle.X509.X509Certificate)pemReader.ReadObject(); } // PKCS12の生成 var certEntry = new X509CertificateEntry(readedCert); var keyEntry = new AsymmetricKeyEntry(privateKey.Private); Pkcs12Store store = new Pkcs12Store(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; chain[0] = new X509CertificateEntry(readedCert); store.SetKeyEntry("privateKey", new AsymmetricKeyEntry(privateKey.Private), chain); var stream = new MemoryStream(); store.Save(stream, pass.ToCharArray(), new SecureRandom()); //p12形式にして変数に保存 this.cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(stream.GetBuffer(), pass, X509KeyStorageFlags.MachineKeySet); //有効期限チェック if (DateTime.Now < this.cert.NotAfter) { return true; } else { MessageBox.Show("証明書ファイルの有効期限が切れています。","エラー",MessageBoxButtons.OK,MessageBoxIcon.Error); return false; } } } } |
上記のサンプルコードのプロジェクトはこちらからダウンロードすることができます。