Python OpenSSL生成证书的步骤
1. 生成私钥
第一步是生成一个私钥,私钥是证书的核心组成部分。在Python中,我们可以使用cryptography
库来生成私钥。下面是生成私钥的代码:
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
# 生成私钥
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
# 将私钥序列化为PEM格式
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
# 将私钥保存到文件
with open('private_key.pem', 'wb') as f:
f.write(pem)
上述代码中,我们首先导入了cryptography
库中相关的模块。然后使用generate_private_key
函数生成一个私钥对象。public_exponent
参数指定了公钥中的指数值,一般使用65537。key_size
参数指定了私钥的位数,一般使用2048位。接下来,我们将私钥序列化为PEM格式,并将其保存到文件中。
2. 生成证书签名请求(CSR)
第二步是生成一个证书签名请求(CSR),CSR包含了证书的信息,如公钥、组织名称等。同样使用cryptography
库,下面是生成CSR的代码:
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.backends import default_backend
# 构造CSR主题
subject = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, u"CN"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Beijing"),
x509.NameAttribute(NameOID.LOCALITY_NAME, u"Beijing"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Your Organization"),
x509.NameAttribute(NameOID.COMMON_NAME, u"example.com"),
])
# 生成CSR
csr = x509.CertificateSigningRequestBuilder().subject_name(
subject
).sign(
private_key, hashes.SHA256(), default_backend()
)
# 将CSR序列化为PEM格式
csr_pem = csr.public_bytes(serialization.Encoding.PEM)
# 将CSR保存到文件
with open("csr.pem", "wb") as f:
f.write(csr_pem)
上述代码中,我们使用x509.NameAttribute
来构造CSR的主题信息,包括国家、省/州、城市、组织名称和通用名称。然后使用CertificateSigningRequestBuilder
对象构造CSR,并使用私钥对其进行签名。最后将CSR序列化为PEM格式,并保存到文件中。
3. 使用私钥签名CSR生成证书
第三步是使用私钥对CSR进行签名,生成最终的证书。同样使用cryptography
库,下面是生成证书的代码:
from cryptography import x509
from cryptography.x509.oid import ExtensionOID
from cryptography.hazmat.primitives import asymmetric
from cryptography.hazmat.primitives import hashes
# 生成证书有效期
not_valid_before = datetime.datetime.utcnow()
not_valid_after = not_valid_before + datetime.timedelta(days=365)
# 构造证书主题
subject = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, u"CN"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Beijing"),
x509.NameAttribute(NameOID.LOCALITY_NAME, u"Beijing"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Your Organization"),
x509.NameAttribute(NameOID.COMMON_NAME, u"example.com"),
])
# 构造证书颁发者
issuer = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, u"CN"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Beijing"),
x509.NameAttribute(NameOID.LOCALITY_NAME, u"Beijing"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Your Organization"),
])
# 构造证书扩展
extensions = [
x509.BasicConstraints(ca=False, path_length=None),
x509.SubjectKeyIdentifier.from_public_key(
private_key.public_key()
),
x509.AuthorityKeyIdentifier.from_issuer_public_key(
private_key.public_key()
).serial_number,
x509.SubjectAlternativeName([
x509.DNSName(u"example.com"),
]),
]
# 生成证书
certificate