我有一个骨架 - 工作,但我有点坚持以下;
非常感谢任何帮助;代码到目前为止 -
#!/usr/bin/env python
from OpenSSL import crypto, SSL
import subprocess, os, sys
# Create 'usage' portion
# Something, blah blah, use script like this, blah blah.
# Variable
TYPE_RSA = crypto.TYPE_RSA
# Generate pkey
def generateKey(type, bits):
keyfile = 'incommon.key'
key = crypto.PKey()
key.generate_key(type, bits)
if os.path.exists(keyfile):
print "Certificate file exists, aborting."
print " ", keyfile
sys.exit(1)
else:
f = open(keyfile, "w")
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
f.close()
return key
# Generate CSR
def generateCSR(nodename):
csrfile = 'incommon.csr'
req = crypto.X509Req()
# Return an X509Name object representing the subject of the certificate.
req.get_subject().CN = nodename
#req.get_subject().countryName = 'xxx'
#req.get_subject().stateOrProvinceName = 'xxx'
#req.get_subject().localityName = 'xxx'
#req.get_subject().organizationName = 'xxx'
#req.get_subject().organizationalUnitName = 'xxx'
# Set the public key of the certificate to pkey.
req.set_pubkey(key)
# Sign the certificate, using the key pkey and the message digest algorithm identified by the string digest.
req.sign(key, "sha1")
# Dump the certificate request req into a buffer string encoded with the type type.
if os.path.exists(csrfile):
print "Certificate file exists, aborting."
print " ", csrfile
sys.exit(1)
else:
f = open('incommon.csr', "w")
f.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))
f.close()
#Call key & CSR functions
key = generateKey(TYPE_RSA,2048)
# Needs to take input from user.
generateCSR('test.test.edu')
编辑:
我最近刚刚解决这个问题。这是带有附加扩展名的代码,或者您可以从我的Github克隆它:https://github.com/cjcotton/python-csr;
# Generate Certificate Signing Request (CSR)
def generateCSR(nodename, sans = []):
C = raw_input('Enter your country: ')
ST = raw_input("Enter your state: ")
L = raw_input("Enter your location: ")
O = raw_input("Enter your organization: ")
OU = raw_input("Enter your organizational unit: ")
# Allows you to permanently set values required for CSR
# To use, comment raw_input and uncomment this section.
# C = 'US'
# ST = 'New York'
# L = 'Location'
# O = 'Organization'
# OU = 'Organizational Unit'
csrfile = 'host.csr'
keyfile = 'host.key'
TYPE_RSA = crypto.TYPE_RSA
# Appends SAN to have 'DNS:'
ss = []
for i in sans:
ss.append("DNS: %s" % i)
ss = ", ".join(ss)
req = crypto.X509Req()
req.get_subject().CN = nodename
req.get_subject().countryName = C
req.get_subject().stateOrProvinceName = ST
req.get_subject().localityName = L
req.get_subject().organizationName = O
req.get_subject().organizationalUnitName = OU
# Add in extensions
base_constraints = ([
crypto.X509Extension("keyUsage", False, "Digital Signature, Non Repudiation, Key Encipherment"),
crypto.X509Extension("basicConstraints", False, "CA:FALSE"),
])
x509_extensions = base_constraints
# If there are SAN entries, append the base_constraints to include them.
if ss:
san_constraint = crypto.X509Extension("subjectAltName", False, ss)
x509_extensions.append(san_constraint)
req.add_extensions(x509_extensions)
# Utilizes generateKey function to kick off key generation.
key = generateKey(TYPE_RSA, 2048)
req.set_pubkey(key)
req.sign(key, "sha1")
generateFiles(csrfile, req)
generateFiles(keyfile, key)
return req
答案 0 :(得分:7)
关于如何将SAN添加到CSR的第一个问题,请考虑在X509req
对象上使用add_extensions
方法(docs for the X509req
class中奇怪地未提及)< / p>
它看起来像这样
altnames = ', '.join(['DNS:foo.example.com',
'DNS:bar.example.com',
'IP:203.0.113.12'])
req.add_extensions([OpenSSL.crypto.X509Extension("subjectAltName",
False,
altnames)])
更新:感谢Peter Gallagher在我的原始答案中捕获了缺失的类型前缀(例如DNS
,IP
)。
答案 1 :(得分:3)
Gene的答案很接近,但每个Subject Alternative Name must be prefixed with a type例如DNS,IP,电子邮件等。假设您需要DNS,以下代码将起作用:
aliases = ['test1.example.com', 'test2.example.com']
if aliases:
subject_alt_names = []
for alias in aliases:
subject_alt_names.append("DNS:{}".format(alias))
req.add_extensions([crypto.X509Extension("subjectAltName", False, ",".join(subject_alt_names))])