python2.7
x509

pythonでx509証明書のCSRの作成

More than 1 year has passed since last update.

はじめに

pythonでx509証明書のパースをしたかったのでその覚書。チュートリアルで最初にCSRを作成したので本ページではそれを纏める。

pythonの標準ライブラリではx509証明書をパース出来ない模様。
そこでadd-on packageのcryptographyをここでは利用する。
https://cryptography.io/

Python 2.7.11で実施。

cryptographyのインストール

インストールはpipで以下の通り。

pip install cryptography

CSRの作成

ソースは以下の通り。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography import x509
from cryptography.x509.oid import NameOID

def gen_rsa_key():
    return rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )

def gen_ec_key():
    return ec.generate_private_key(
        ec.SECP384R1(), default_backend()
    )

def gen_csr(key, c, s, l, o, cn):
    return x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, c),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, s),
        x509.NameAttribute(NameOID.LOCALITY_NAME, l),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, o),
        x509.NameAttribute(NameOID.COMMON_NAME, cn),
    ])).sign(key, hashes.SHA256(), default_backend())

def write_key(key, pass_phrase, path):
    with open(path, "wb") as f:
        f.write(key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.BestAvailableEncryption(pass_phrase),
        ))

def write_csr(csr, path):
    with open(path, "wb") as f:
        f.write(csr.public_bytes(serialization.Encoding.PEM))
.
# RSAのkeyを利用したCSR
rsa_key = gen_rsa_key()
rsa_csr = gen_csr(rsa_key, u"JP", u"Tokyo", u"Shibuya", u"Company name", u"example.jp")
write_key(rsa_key, b"password", "/home/hoge/rsa.key")
write_csr(rsa_csr, "/home/hoge/rsa.csr")

# ECのkeyを利用したCSR
ec_key = gen_ec_key()
ec_csr = gen_csr(ec_key, u"JP", u"Tokyo", u"Shibuya", u"Company name", u"example.jp")
write_key(ec_key, b"password", "/home/hoge/ec.key")
write_csr(ec_csr, "/home/hoge/ec.csr")

と終わらせるのも何なので、少し解説。

1.鍵生成

まず秘密鍵と公開鍵のペアを生成する。

サーバ鍵生成などで用いられるものの主流はRSA 2048bit。ECDH/ECDSA P256, ECDH/ECDSA P384なども使われている。

楕円曲線パラメータはいろいろある。
P256(=SECP256R1), P384(=SECP384R1)あたりが証明書としては多く使われているイメージ。
ちなみにビットコインで利用している暗号形式はSECP256K1。

2.CSR生成

ここでは、COUNTRY_NAME, STATE_OR_PROVINCE_NAME, LOCALITY_NAME,
ORGANIZATION_NAME, COMMON_NAMEを入力。
さらに、先ほど作った公開鍵を秘密鍵とSHA256を使って署名。
サーバ証明書ではこの公開鍵をCAの秘密鍵で署名することになる。

入力する情報としてはORGANIZATIONAL_UNIT_NAME, EMAIL_ADDRESSもよくつかわれる。