C#で証明書ファイル(CRTファイル)とキーファイル(KEYファイル)を読み込む場合、OpenSSLなどを利用して、P12ファイルに変換する必要があります。

システムエンジニアでは無い、一般の人にはP12ファイルへの変換は抵抗感を感じてしまいます。

 

ですので、以前からC#で直接CRTファイルとKEYファイルを読み込めないか?考えていましたが、最近方法を見つけたので記事にしてみました。

 

使用した開発環境はVisual Studio Community 2019 になります。

 

 

NuGetで「BouncyCastle」を追加する

プロジェクトを開いて、「ツール」→「NuGetパッケージマネージャー」→「ソリューションのNuGetパッケージの管理」を開きます。

BouncyCastle

 

参照タブを開いて検索窓に「BouncyCastle」と入力し、「BouncyCastle」を選択してインストールします。

 

CRTファイルとKEYファイル読み込みサンプル

Yahooショッピングの注文APIサンプルでも作成しようかとも思いましたが、なるべくシンプルにしました。

 

作成したフォームはこんな感じです。

 

フォームクラスに、public変数「cert」を宣言し、読み込んだCRTファイルとKEYファイルでP12形式の値にしています。

 

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;
            }
        }


    }
}

 

上記のサンプルコードのプロジェクトはこちらからダウンロードすることができます。

 

[wpdm_package id=’900′]

 

 

By にど寝

もともと名古屋でシステムエンジニアをしてましたが、現在は地元に帰省してネットショップの社内システムエンジニアをしてます。  

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です