📑

超絶シンプルな自己署名証明書作成の手段を用意した(SAN付き)

2024/04/22に公開

結論

これだけでオレオレCAとオレオレサーバ証明書を生成できます。(python利用可能が前提)

CommonNameは--cnで指定。
SANを--sansで指定(オプション)。
有効期限はデフォルトで365日(--daysで指定可能)

$ git clone https://github.com/knziiy/SelfSignedCertGenerator.git
$ cd SelfSignedCertGenerator
$ pip install cryptography
$ python generate-ca-and-certificate.py --cn example.com --sans www.example.com
File saved: example.com/ca_private_key.pem
File saved: example.com/ca_certificate.pem
File saved: example.com/server_private_key.pem
File saved: example.com/server_certificate.pem
File saved: example.com/server_csr.pem

課題

テスト用や開発用に自己署名のSSLサーバ証明書(オレオレ証明書)を用意したくなることがあると思いますが、その度にググって、opensslコマンドで

  1. CAの秘密鍵作る
  2. CAの証明書作る
  3. サーバ証明書用の秘密鍵作る
  4. サーバ証明書用のCSR作る
  5. サーバ証明書用のCSRとCAで自己署名サーバ証明書作る

をするわけですが毎回忘れるしとにかくめんどくさい。
しかもChromeだとSANも設定しておかないとCAの証明書を信頼させても自己署名証明書に警告やエラーが出るし・・・

解決策

ということでPythonで簡単なスクリプトを用意しました。

https://github.com/knziiy/SelfSignedCertGenerator

https://github.com/knziiy/SelfSignedCertGenerator/blob/main/generate-ca-and-certificate.py

使い方

pythonが利用できる必要があります。
pipでcryptographyだけインストールが必要です。

pip install cryptography

ほとんどのことはハードコードしてしまっているので、指定するのはサーバ証明書にセットしたいCN(CommonName)と、SANだけです。
SANにセットしたい値は--sansのオプションに対して空白区切りでいくつでも指定可能です。

$ git clone https://github.com/knziiy/SelfSignedCertGenerator.git
$ cd SelfSignedCertGenerator
$ python generate-ca-and-certificate.py --cn example.com --sans www.example.com
File saved: example.com/ca_private_key.pem
File saved: example.com/ca_certificate.pem
File saved: example.com/server_private_key.pem
File saved: example.com/server_certificate.pem
File saved: example.com/server_csr.pem

これだけ。

これで、カレントディレクトリ配下にexample.comディレクトリが作成されて、以下のようなファイルができます。

ca_certificate.pem       # CAの証明書です。これをブラウザなり、サーバ、PCなりに信頼させればOK
ca_private_key.pem       # CAの秘密鍵です
server_certificate.pem   # 自己署名サーバ証明書です。これをWebサーバにセット。
server_csr.pem           # サーバ証明書のCSRです。もういらない
server_private_key.pem   # サーバ証明書の秘密鍵です。サーバ証明書といっしょにWebサーバにセットしましょう。

注意事項

なにせ手数を減らしたかったのでいろいろとハードコードしてしまっています。
具体的にはCA証明書、サーバ証明書のCOUNTRY_NAMEなどの属性値が固定なのと、
証明書の有効期限はデフォルトで365日になっています。
変更したい場合は --days 730 のように--daysオプションで指定してください。

CAのNameAttribute

    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "JP"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Tokyo"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Minato"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "My CA Organization"),
        x509.NameAttribute(NameOID.COMMON_NAME, "My CA"),
    ])

サーバ証明書のNameAttribute

    csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "JP"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Tokyo"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Minato"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "My Server Organization"),
        x509.NameAttribute(NameOID.COMMON_NAME, cn),
    ]))

Discussion