#はじめに
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もよくつかわれる。