C#でクライアント証明書を作成するサンプルを探しても見つからなかったので、備忘録として記事にしました。
using System.Text;
using System.Security.Cryptography.X509Certificates;
// ルート証明書ファイルの読み込み
var rootCertificate = X509Certificate2.CreateFromPemFile("ca.crt", "ca.key");
// 2048bit長でキーペア(公開鍵・秘密鍵)を生成
using (System.Security.Cryptography.RSACryptoServiceProvider rsa =
new System.Security.Cryptography.RSACryptoServiceProvider(2048))
{
// 公開鍵を取得
byte[] bytesPublicKey = rsa.ExportRSAPublicKey();
// 秘密鍵を取得
byte[] bytesPrivateKey = rsa.ExportRSAPrivateKey();
// クライアント証明書に使用するサブジェクトを生成
X500DistinguishedName subjectName = new X500DistinguishedName("C=JP\nST=XXX\nL=YYY\nO=ZZZ\nCN=hogehoge", X500DistinguishedNameFlags.UseNewLines);
// CSR(Certificate Signing Request)を生成
var certificateRequest = new CertificateRequest
(
subjectName,
rsa,
System.Security.Cryptography.HashAlgorithmName.SHA256,
// System.Security.Cryptography.RSASignaturePadding.Pss
System.Security.Cryptography.RSASignaturePadding.Pkcs1
);
// CSRからルート証明書の秘密鍵で署名されたクライアント証明書を作成(この証明書に秘密鍵は含まれていない)
var serialNumber = new byte[] { 0x01 }; // クライアント証明書に使用するシリアル番号を指定する
X509Certificate2 clientCertificateNotHasPrivateKey = certificateRequest.Create
(
rootCertificate,
DateTimeOffset.Now.AddDays(-1), // この証明書が有効と見なされる最も古い日時。
DateTimeOffset.Now.AddDays(1), // この証明書が有効と見なされなくなった日時。
serialNumber // クライアント証明書に使用するシリアル番号。
);
// 証明書をPem(Base64)形式の文字列で取得
StringBuilder clientCertificateNotHasPrivateKeyPem = new StringBuilder();
clientCertificateNotHasPrivateKeyPem.AppendLine("-----BEGIN CERTIFICATE-----");
clientCertificateNotHasPrivateKeyPem.AppendLine(Convert.ToBase64String(clientCertificateNotHasPrivateKey.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
clientCertificateNotHasPrivateKeyPem.AppendLine("-----END CERTIFICATE-----");
// 秘密鍵をPem(Base64)形式の文字列で取得
StringBuilder privateKeyPem = new StringBuilder();
privateKeyPem.AppendLine("-----BEGIN RSA PRIVATE KEY-----");
privateKeyPem.AppendLine(Convert.ToBase64String(bytesPrivateKey, Base64FormattingOptions.InsertLineBreaks));
privateKeyPem.AppendLine("-----END RSA PRIVATE KEY-----");
// Pem形式の証明書と秘密鍵からPfxファイルを作成
var clientCertificate = X509Certificate2.CreateFromPem(clientCertificateNotHasPrivateKeyPem.ToString().ToCharArray(), privateKeyPem.ToString().ToCharArray());
var clientCertificatePfx = clientCertificate.Export(X509ContentType.Pfx, "password");
File.WriteAllBytes("clientCertificate.pfx", clientCertificatePfx);
}