簡體   English   中英

如何使用Python的pyOpenSSL創建和簽署證書?

[英]How do I create and sign certificates with Python's pyOpenSSL?

我想使用python創建一個CA證書,以及我用它簽名的客戶端證書。 我將在OpenVPN中使用它們。 經過幾天的研究和反復試驗,這就是我想出來的:

#!/usr/bin/env python

import os
import sys
import random
from OpenSSL import crypto

###########
# CA Cert #
###########

ca_key = crypto.PKey()
ca_key.generate_key(crypto.TYPE_RSA, 2048)

ca_cert = crypto.X509()
ca_cert.set_version(2)
ca_cert.set_serial_number(random.randint(50000000,100000000))

ca_subj = ca_cert.get_subject()
ca_subj.commonName = "My CA"

ca_cert.add_extensions([
    crypto.X509Extension("subjectKeyIdentifier", False, "hash", subject=ca_cert),
])

ca_cert.add_extensions([
    crypto.X509Extension("authorityKeyIdentifier", False, "keyid:always", issuer=ca_cert),
])

ca_cert.add_extensions([
    crypto.X509Extension("basicConstraints", False, "CA:TRUE"),
    crypto.X509Extension("keyUsage", False, "keyCertSign, cRLSign"),
])

ca_cert.set_issuer(ca_subj)
ca_cert.set_pubkey(ca_key)
ca_cert.sign(ca_key, 'sha256')

ca_cert.gmtime_adj_notBefore(0)
ca_cert.gmtime_adj_notAfter(10*365*24*60*60)

# Save certificate
with open("ca.crt", "wt") as f:
    f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, ca_cert))

# Save private key
with open("ca.key", "wt") as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, ca_key))

###############
# Client Cert #
###############

client_key = crypto.PKey()
client_key.generate_key(crypto.TYPE_RSA, 2048)

client_cert = crypto.X509()
client_cert.set_version(2)
client_cert.set_serial_number(random.randint(50000000,100000000))

client_subj = client_cert.get_subject()
client_subj.commonName = "Client"

client_cert.add_extensions([
    crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
    crypto.X509Extension("subjectKeyIdentifier", False, "hash", subject=client_cert),
])

client_cert.add_extensions([
    crypto.X509Extension("authorityKeyIdentifier", False, "keyid:always", issuer=ca_cert),
    crypto.X509Extension("extendedKeyUsage", False, "clientAuth"),
    crypto.X509Extension("keyUsage", False, "digitalSignature"),
])

client_cert.set_issuer(ca_subj)
client_cert.set_pubkey(client_key)
client_cert.sign(ca_key, 'sha256')

client_cert.gmtime_adj_notBefore(0)
client_cert.gmtime_adj_notAfter(10*365*24*60*60)

# Save certificate
with open("client.crt", "wt") as f:
    f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, client_cert))

# Save private key
with open("client.key", "wt") as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, client_key))

這會生成證書和私鑰,但不幸的是,我必須做錯事,因為他們不會驗證:

$ openssl verify -verbose -CAfile ca.crt client.crt
client.crt: CN = Client
error 7 at 0 depth lookup:certificate signature failure
139823049836448:error:04091068:rsa routines:INT_RSA_VERIFY:bad signature:rsa_sign.c:293:
139823049836448:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:a_verify.c:241:

我究竟做錯了什么?

您在簽署證書后設置notBefore而不是AfterAfter,從而更改已簽名的證書 - 這使簽名不再與證書匹配:

client_cert.sign(ca_key, 'sha256')  

client_cert.gmtime_adj_notBefore(0)
client_cert.gmtime_adj_notAfter(10*365*24*60*60)

# Save certificate
...

如果您將簽名部分移動到最后一步,即在寫入文件之前,則驗證將成功:

client_cert.gmtime_adj_notBefore(0)
client_cert.gmtime_adj_notAfter(10*365*24*60*60)

client_cert.sign(ca_key, 'sha256')  

# Save certificate
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM