1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonで秘密鍵と自己証明書を生成する

Last updated at Posted at 2023-04-05

Pythonで署名をしたい

PythonでPDFに対する署名をテストしたかったため、まずは秘密鍵と自己証明書をワンクリックで生成できるスクリプトを作成してみました(わからない部分は某AIさんにお世話になりました)

私の環境のPythonバージョンが3.8.6と少し古いですが最新のものでも動くと思います(思ってるだけかもしれません)

ライブラリ

ライブラリはcryptographyを使用します。

pip install cryptography

コード

from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import datetime


def generate_private_key():
    # RSA秘密鍵を生成
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    return private_key


def save_private_key_to_pem(private_key, filename):
    # 秘密鍵をPEM形式でファイルに保存
    with open(filename, "wb") as key_file:
        key_file.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        ))


def generate_self_signed_certificate(private_key):
    # 秘密鍵から公開鍵を取得
    public_key = private_key.public_key()

    # 証明書のsubjectとissuerを設定
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u"JP"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Osaka"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u"Osaka"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"xxxxx"),
        x509.NameAttribute(NameOID.COMMON_NAME, u"xxxxx.com"),
    ])

    # 自己署名証明書を生成
    cert = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        public_key
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.datetime.utcnow()
    ).not_valid_after(
        # 証明書の有効期限を1年後に設定
        datetime.datetime.utcnow() + datetime.timedelta(days=365)
    ).add_extension(
        # Subject Alternative Nameを追加
        x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),
        critical=False,
    ).sign(private_key, hashes.SHA256())

    return cert


def save_certificate_to_pem(cert, filename):
    # 証明書をPEM形式でファイルに保存
    with open(filename, "wb") as cert_file:
        cert_file.write(cert.public_bytes(serialization.Encoding.PEM))


def main():
    # 秘密鍵の生成と保存
    private_key = generate_private_key()
    save_private_key_to_pem(private_key, "private_key.pem")

    # 自己署名証明書の生成と保存
    cert = generate_self_signed_certificate(private_key)
    save_certificate_to_pem(cert, "certificate.pem")


if __name__ == "__main__":
    main()

上記コードを実行すると同階層のフォルダ内にprivate_key.pem(秘密鍵)とcertificate.pem(自己証明書)が生成されます。簡単!!

PDFへの署名に関しては出来次第投稿しようと思っています。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?