使用Python生成CSR(加密)

时间:2014-06-04 16:52:56

标签: python

我有一个骨架 - 工作,但我有点坚持以下;

  1. 我没有看到使用加密库处理SAN的方法(subjectAltName)?希望我在术语上没有错,但如果我说 - 一个主要的主机名test.test.edu然后或者希望那个主机也是pushu.edu,通常可以是"的SubjectAltName"
  2. 有没有办法看到整个CSR?比如,它显示主题,国家等等?我只是想看到它打印到屏幕上,但我没有看到用加密技术做到这一点的方法。
  3. 非常感谢任何帮助;代码到目前为止 -

    #!/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
    

2 个答案:

答案 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在我的原始答案中捕获了缺失的类型前缀(例如DNSIP)。


答案 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))])