今回の多部構成の記事では、Pythonを使ったLet's Encrypt ACME version 2 APIをSSL証明書に利用する方法を学びます。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
アカウントキー
アカウント・キーは、証明書サービスを要求しているアカウントの ID を提供するために使用されます。ログイン/パスワードなどの方法は使用されません。アカウントキーはSSL証明書の発行、更新、失効に使用されるため、アカウントキーのペアを安全な場所に保存しておくことが非常に重要です。アカウントキーを紛失した場合、そのアカウントの下で作成された証明書は保留状態になります。これらの証明書を更新したり失効させたりすることはできません。この場合、新しいアカウントキーを作成して、管理を失った証明書の代わりに新しいSSL証明書を発行する必要があります。悪意のある第三者がアカウントキーへのアクセスを取得した場合、連絡先のメールアドレスを変更し、証明書を失効させることができます。ドメイン名の HTTP または DNS の検証が必要となるため、ドメインの新しい SSL 証明書を発行することはできません。
秘密鍵のサイズに関するドキュメントを見つけることができませんでした。私は4096ビットの鍵サイズでテストしていますが、これは問題なく動作します。
アカウント鍵を作成する方法は数多くあります。Python プログラムを書く方法と、コマンドラインから OpenSSL を使う方法の 2 つを見てみましょう。秘密鍵を使用する方法を示す例が含まれています。
この例では openssl python ライブラリは使用していません。この例では、秘密鍵の作成を非常に簡単にするcryptoライブラリを使用しています。次の例はopensslを使用したもので、より複雑ですが、より多くのオプションが用意されています。
make_account_key.py
""" Let's Encrypt ACME Version 2 Examples - Create Account Key """
from Crypto.PublicKey import RSA
filename = 'account.key'
key = RSA.generate(4096)
with open(filename,'w') as f:
f.write(key.exportKey().decode('utf-8'))
make_account_key2.py
import sys
import OpenSSL
from OpenSSL import crypto
filename = 'account.key'
key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 4096)
key_material = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)
val = key_material.decode('utf-8')
with open("account.key", "wt") as f:
f.write(val)
OpenSSLコマンドラインの例
openssl genrsa -out account.key 4096
OpenSSL コマンドラインオプション
1、genrsa - RSA 秘密鍵 (PKCS#1 形式) を生成します。
2、-out filename - 指定したファイルにキーを出力します。
3、4096 - ビット単位で生成される秘密鍵のサイズ
詳細を表示し、新しいアカウントキーを確認します。
openssl rsa -in account.key -text -check -noout
秘密鍵から公開鍵を抽出します。
openssl rsa -pubout -in account.key -out account.pub
証明書キー
証明書キーは、CSR(証明書署名要求)に署名するために使用されるキーペアです。両方ともキー・ペアであるにもかかわらず、これはアカウント・キーではありません。セキュリティ上の理由から、アカウント鍵をCSRに署名するのは避けた方が良いでしょう。一般的には、SSL証明書ごとに新しい証明書キーを作成するのが一般的です。
上記の例を繰り返して証明書キーを作成します。違いは、ファイル名が証明書を発行するドメイン名になることです。domain.com」をドメイン名に変更します。
make_certificate_key.py
""" Let's Encrypt ACME Version 2 Examples - Create Certificate Key """
from Crypto.PublicKey import RSA
domainname = "example.com"
filename = domainname + '.key'
key = RSA.generate(4096)
with open(filename,'w') as f:
f.write(key.exportKey().decode('utf-8'))
OpenSSLコマンドラインの例。
openssl genrsa -out example.com.key 4096
OpenSSL コマンドラインオプション。
1、genrsa - RSA 秘密鍵 (PKCS#1 形式) を生成します。
2、-out filename - 指定したファイルにキーを出力します。
3、4096 - ビット単位で生成される秘密鍵のサイズ
CSR - 証明書署名要求
CSRとは、SSL証明書を申請するためにCA(Certificate Authority - Let's Encrypt)に送るファイル(メッセージ)のことです。CSRには、SSL証明書を申請する人の会社名、所在地、ドメイン名などの詳細が記載されています。Let's EncryptはDV(Domain Validated)SSL証明書のみを発行しているため、生成されたSSL証明書にはドメイン名のみが検証され、そのドメイン名のみが記載されているほか、連絡先を記載するためのオプションのメールアドレスも記載されています。会社名や所在地などの詳細は含まれません。
CSRの生成はOpenSSLを使えば簡単です。必要なのは、ドメイン名とオプションでメールアドレスだけです。次の例では、 domainName をドメイン名に、emailAddress をメールアドレスに置き換えます。
この例では、Let's Encrypt が処理しない C, ST, L, O, OU などの件名フィールドをすべて削除し、Chrome が必要とする subjectAltName 拡張機能を追加しています。
make_csr.py
""" Let's Encrypt ACME Version 2 Examples - Create CSR (Certificate Signing Request) """
importOpenSSL
KEY_FILE = "certificate.key"
CSR_FILE = "certificate.csr"
domainName = 'api.neoprime.xyz'
emailAddress = 'support@neoprime.xyz'
def create_csr(pkey, domain_name, email_address):
""" Generate a certificate signing request """
# create certificate request
cert = OpenSSL.crypto.X509Req()
# Add the email address
cert.get_subject().emailAddress = email_address
# Add the domain name
cert.get_subject().CN = domain_name
san_list = ["DNS:" + domain_name]
cert.add_extensions([
OpenSSL.crypto.X509Extension(
b"subjectAltName",
False,
", ".join(san_list).encode("utf-8"))
])
cert.set_pubkey(pkey)
cert.sign(pkey, 'sha256')
return cert
# Load the Certicate Key
data = open(KEY_FILE, 'rt').read()
# Load the private key from the certificate.key file
pkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, data)
# Create the CSR
cert = create_csr(pkey, domainName, emailAddress)
# Write the CSR to a file in PEM format
with open(CSR_FILE,'wt') as f:
data = OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_PEM, cert)
f.write(data.decode('utf-8'))
概要
パート3では、account.key、certificate.key、certificate.csrファイルを使用して、Alibaba Cloud API GatewayとCDN用のSSL証明書を生成してインストールするために、Let's Encrypt ACME APIの各項目について説明します。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ