0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自己署名証明書を理解したい

Last updated at Posted at 2025-09-04

1. はじめに

やってみた自分用メモ。「自己署名証明書」を作れたのはいいのですが、CreateSelfSigned という関数に隠されていて、よくわかりませんでした。

拙作ですみませんが

ということで、もうちょっと細かい制御ができる BouncyCastleで見てみたいと思います。こういう「なぜ?と思う横道」は大切だと思います。

2. いきなりコード

ChatGPTの出力が元になっています。利用される方は自己責任で。

sample.cs
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;


class Program
{
    static void Main()
    {
        string subjectName = "CN=localhost";
        string[] sanNames = { "localhost", "example.com", "127.0.0.1", "::1" };
        int validityDays = 365;
        string pfxPassword = "p@ssw0rd";

        X509Certificate2 cert = GenerateSelfSignedCertificateWithSAN(subjectName, sanNames, validityDays, pfxPassword);

        File.WriteAllBytes("mycert_san.pfx", cert.Export(X509ContentType.Pfx, pfxPassword));
        Console.WriteLine("SAN付き自己署名証明書を作成しました: mycert_san.pfx");
    }

    static X509Certificate2 GenerateSelfSignedCertificateWithSAN(string subjectName, string[] sanNames, int validityDays, string pfxPassword)
    {
        var keyGen = new RsaKeyPairGenerator();
        keyGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
        var keyPair = keyGen.GenerateKeyPair();

        var certGen = new X509V3CertificateGenerator();
        certGen.SetSerialNumber(BigInteger.ProbablePrime(120, new SecureRandom()));
        // 対象=承認者 なので「自己署名証明書」
        // 対象
        certGen.SetSubjectDN(new X509Name(subjectName));
        // 承認者
        certGen.SetIssuerDN(new X509Name(subjectName));
        certGen.SetNotBefore(DateTime.UtcNow);
        certGen.SetNotAfter(DateTime.UtcNow.AddDays(validityDays));
        certGen.SetPublicKey(keyPair.Public);

        var sanList = new Asn1Encodable[sanNames.Length];
        for (int i = 0; i < sanNames.Length; i++)
        {
            string name = sanNames[i];
            if (IPAddress.TryParse(name, out _))
            {
                sanList[i] = new GeneralName(GeneralName.IPAddress, name);
            }
            else {
                sanList[i] = new GeneralName(GeneralName.DnsName, name);
            }
        }
        var subjectAltNames = new DerSequence(sanList);
        certGen.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltNames);
        // 「自分で承認した」ことにして、自分の秘密鍵で署名する
        var signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keyPair.Private);
        var certificate = certGen.Generate(signatureFactory);

        var store = new Pkcs12StoreBuilder().Build();
        var certificateEntry = new X509CertificateEntry(certificate);
        store.SetCertificateEntry(subjectName, certificateEntry);
        store.SetKeyEntry(subjectName, new AsymmetricKeyEntry(keyPair.Private), new[] { certificateEntry });

        using (var ms = new MemoryStream())
        {
            store.Save(ms, pfxPassword.ToCharArray(), new SecureRandom());
            return new X509Certificate2(ms.ToArray(), pfxPassword, X509KeyStorageFlags.Exportable);
        }
    }
}

3. 見えてきたもの

コード断片
// 対象=承認者 なので「自己署名証明書」
// 対象
certGen.SetSubjectDN(new X509Name(subjectName));
// 承認者
certGen.SetIssuerDN(new X509Name(subjectName));

// 「自分で承認した」ことにして、自分の秘密鍵で署名する
var signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keyPair.Private);
        

「あ~そういうことね」と納得しました。自己承認なので「Self authorized ~」みたいな用語が正しいのではないかと思っていました。でも承認した結果が署名になっているのでこれでいいのです。むぅ、難しい。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?