Python 创建 X509 签名

2 投票
2 回答
1811 浏览
提问于 2025-04-16 19:34

我想知道怎么用Python创建一个X509签名。

我找不到任何好的例子来解释怎么用Python生成这样的签名。

我的目标是得到类似这样的东西:

-----BEGIN CERTIFICATE-----
MIICjDCCAfWgAwIBAgIJANG2v68GF4y/MA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQKEwhNMkNyeXB0bzEY
MBYGA1UEAxMPSGVpa2tpIFRvaXZvbmVuMB4XDTA5MDcyODA0MzQzNFoXDTE5MDcy
NjA0MzQzNFowRDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAP
BgNVBAoTCE0yQ3J5cHRvMQ0wCwYDVQQDEwRYNTA5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDTYlUSMLjchHxjvYAdGRpy8ij4WQsqa/IqI527D3+SXt0ndLx4
CierHC4jHCZ3SLaPA+9XHKBUrhro9SShRqEnSFUzmPzbaoMuiT/g85Gd2k/bdJCd
po1KRsufurhg367uIks/gFX3HYk8KyjfRhnVGKzpB05AgXW82lvV4cIEFQIDAQAB
o3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUscRvmG/oO4yhJhGBl5oSUEoabIgwHwYD
VR0jBBgwFoAUrWRFdI+DxyzV16CFkRBAmpyWz+4wDQYJKoZIhvcNAQEFBQADgYEA
PwtEvNLaX6k5vghT5v0Q/9bwo1H2vgMgzLNSzw98P1ZCb51ymwmlZD9DKSQr1nmU
VC+Z6M7+/d67ykMoFv8yrD3FVtuHIzzUafdOG8S+ydgnmSpkvjprflGF23U1QKVs
rlPDCecANRdkGhdxxdVZ5Y/8lkr5gTMjTMFgcZMYCsQ=
-----END CERTIFICATE-----

谢谢...

2 个回答

0

之前的回答是通过调用操作系统的命令来实现的,所以它并不适用于所有平台。比如说,这段代码在Windows上就无法运行。

如果想要一个完全用Python写的解决方案,可以使用cryptography这个模块。

https://cryptography.io/en/latest/

from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
import datetime
one_day = datetime.timedelta(1, 0, 0)
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()
builder = x509.CertificateBuilder()
builder = builder.subject_name(x509.Name([
    x509.NameAttribute(NameOID.COMMON_NAME, u'test'),
]))
builder = builder.issuer_name(x509.Name([
    x509.NameAttribute(NameOID.COMMON_NAME, u'test'),
]))
builder = builder.not_valid_before(datetime.datetime.today() - one_day)
builder = builder.not_valid_after(datetime.datetime.today() + (one_day * 30))
builder = builder.serial_number(x509.random_serial_number())
builder = builder.public_key(public_key)
builder = builder.add_extension(
    x509.BasicConstraints(ca=False, path_length=None), critical=True,
)
certificate = builder.sign(
    private_key=private_key, algorithm=hashes.SHA256(),
)
3

这里是最简单的方法

>>> cmd = "openssl req   -x509 -nodes -days 365   -subj '/C=US/ST=Oregon/L=Portland/CN=www.madboa.com'   -newkey rsa:1024 -keyout mycert.pem"
>>> from subprocess import Popen, PIPE
>>> proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
>>> print proc.stdout.read()
-----BEGIN CERTIFICATE-----
MIICvzCCAiigAwIBAgIJAO9AofW3r93ZMA0GCSqGSIb3DQEBBQUAMEoxCzAJBgNV
BAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMRcwFQYD
VQQDEw53d3cubWFkYm9hLmNvbTAeFw0xMTA2MTQyMjE3MzZaFw0xMjA2MTMyMjE3
MzZaMEoxCzAJBgNVBAYTAlVTMQ8wDQYDVQQIEwZPcmVnb24xETAPBgNVBAcTCFBv
cnRsYW5kMRcwFQYDVQQDEw53d3cubWFkYm9hLmNvbTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAk/omGua0jgvVAOvYfRS6Se/5O9opDolw3FguU0+iqz+NViaq
NbcxzuYmWwvy6rS3+MYrvMYY8ii6aAE7QuLryK70JZjDQZZr18HvtZ5Fsso0Y4py
LINVDr2242wBlPm8V+PTsV9uxmeJDuITlzlrX2pdyVPbbJjHjkYOSSx5EhUCAwEA
AaOBrDCBqTAdBgNVHQ4EFgQUQcvE5FPtuZdgsNzY83uC+l4ENZQwegYDVR0jBHMw
cYAUQcvE5FPtuZdgsNzY83uC+l4ENZShTqRMMEoxCzAJBgNVBAYTAlVTMQ8wDQYD
VQQIEwZPcmVnb24xETAPBgNVBAcTCFBvcnRsYW5kMRcwFQYDVQQDEw53d3cubWFk
Ym9hLmNvbYIJAO9AofW3r93ZMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
gYEAMAUvDANYFvHzBMbHG0zmwy0VrifbuK3hp4bhkhIBonttxWrn0TmSFNmiCt5W
UetGj1+NKGBiA3zKRzyW9o05l4rqiwyfNXikrLS1xiFpQ2mHtWWv9T6t0p/CM3Od
UVuH3+QoW0VLLgtoH46nb5VImuryB1NovZo8mjJ0H7b/6WE=
-----END CERTIFICATE-----

所以类似地,使用 'openssl x509' 这个命令,配合正确的选项,然后在 Python 中读取它。如果不行的话,你可以看看 PyCrypto,还有 Google 的 Keyczar

撰写回答