我正在使用this example通过python 2.7.5设置HTTPS / TLS服务器。但是,我尝试使用自定义类'CustomHandler',该类扩展了BaseHTTPRequestHandler以在一个python应用程序中支持HTML和Rest API。我一直牢记在BaseHTTPRequestHandler中调用什么方法来获取用户/客户端证书作为x509.Certificate对象。归根结底,我想从python的SSLSocket对象获得完整的用户/客户端DN。

我发现self.connection.getpeercert()可以将字典对象返回为documented here

{'issuer': ((('countryName', 'IL'),),
            (('organizationName', 'StartCom Ltd.'),),
            (('organizationalUnitName',
              'Secure Digital Certificate Signing'),),
            (('commonName',
              'StartCom Class 2 Primary Intermediate Server CA'),)),
 'notAfter': 'Nov 22 08:15:19 2013 GMT',
 'notBefore': 'Nov 21 03:09:52 2011 GMT',
 'serialNumber': '95F0',
 'subject': ((('description', '571208-SLe257oHY9fVQ07Z'),),
             (('countryName', 'US'),),
             (('stateOrProvinceName', 'California'),),
             (('localityName', 'San Francisco'),),
             (('organizationName', 'Electronic Frontier Foundation, Inc.'),),
             (('commonName', '*.eff.org'),),
             (('emailAddress', '[email protected]'),)),
 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')),
 'version': 3}


设置开始工作...

sudo apt-get install python
sudo apt-get install python-pip
pip install cryptography

# Generate Certificates - Root Certificate
sudo openssl req -out ca.pem -new -x509
...Generating a 2048 bit RSA private key
........................+++
.........+++
...writing new private key to 'privkey.pem'
...Enter PEM pass phrase:password
...Verifying - Enter PEM pass phrase:password
...-----
...You are about to be asked to enter information that will be incorporated
...into your certificate request.
...What you are about to enter is what is called a Distinguished Name or a DN.
...There are quite a few fields but you can leave some blank
...For some fields there will be a default value,
...If you enter '.', the field will be left blank.
...-----
...Country Name (2 letter code) [AU]:US
...State or Province Name (full name) [Some-State]:Florida
...Locality Name (eg, city) []:Tampa
...Organization Name (eg, company) [Internet Widgits Pty Ltd]:Home
...Organizational Unit Name (eg, section) []:Development
...Common Name (e.g. server FQDN or YOUR name) []:Home Development
...Email Address []:[email protected]
# IMPORT THE ca.pem file into your browser's Certificate Authorities

# Generate Certificates - Server certificates
sudo openssl genrsa -out server.key 1024
sudo openssl req -key server.key -new -out server.req
...You are about to be asked to enter information that will be incorporated
...into your certificate request.
...What you are about to enter is what is called a Distinguished Name or a DN.
...There are quite a few fields but you can leave some blank
...For some fields there will be a default value,
...If you enter '.', the field will be left blank.
...-----
...Country Name (2 letter code) [AU]:US
...State or Province Name (full name) [Some-State]:Florida
...Locality Name (eg, city) []:Tampa
...Organization Name (eg, company) [Internet Widgits Pty Ltd]:Home
...Organizational Unit Name (eg, section) []:Development
...Common Name (e.g. server FQDN or YOUR name) []:homeoffice.com
...Email Address []:[email protected]
...
...Please enter the following 'extra' attributes
...to be sent with your certificate request
...A challenge password []:
...An optional company name []:
vi file.srl
...00
vi server.ext
...authorityKeyIdentifier=keyid,issuer
...basicConstraints=CA:FALSE
...keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
...subjectAltName = @alt_names
...
...[alt_names]
...DNS.1 = homeoffice.com
sudo openssl x509 -req -in server.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out server.pem -days 1825 -sha256 -extfile server.ext
...Signature ok
...subject=C = US, ST = Florida, L = Tampa, O = Home, OU = Development, CN = Home Development, emailAddress = [email protected]
...Getting CA Private Key
...Enter pass phrase for privkey.pem:password

# Generate Certificates - Client Certificates
sudo openssl genrsa -des3 -out client.key 1024
...Generating RSA private key, 1024 bit long modulus
......................................++++++
.....................................++++++
...e is 65537 (0x010001)
...Enter pass phrase for client.key:password
...Verifying - Enter pass phrase for client.key:password
sudo openssl req -key client.key -new -out client.req
...Enter pass phrase for client.key:password
...You are about to be asked to enter information that will be incorporated
...into your certificate request.
...What you are about to enter is what is called a Distinguished Name or a DN.
...There are quite a few fields but you can leave some blank
...For some fields there will be a default value,
...If you enter '.', the field will be left blank.
...-----
...Country Name (2 letter code) [AU]:US
...State or Province Name (full name) [Some-State]:Florida
...Locality Name (eg, city) []:Tampa
...Organization Name (eg, company) [Internet Widgits Pty Ltd]:Home
...Organizational Unit Name (eg, section) []:Development
...Common Name (e.g. server FQDN or YOUR name) []:Smith John J jjsmith3
...Email Address []:[email protected]
...
...Please enter the following 'extra' attributes
...to be sent with your certificate request
...A challenge password []:
...An optional company name []:
sudo openssl x509 -req -in client.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out client.pem
...Signature ok
...subject=C = US, ST = Florida, L = Tampa, O = Home, OU = Development, CN = Home Development, emailAddress = [email protected]
...Getting CA Private Key
...Enter pass phrase for privkey.pem:password
sudo openssl pkcs12 -export -out client.p12 -in client.pem -inkey client.key
...Enter pass phrase for client.key:password
...Enter Export Password:password
...Verifying - Enter Export Password:password
# IMPORT THE client.p12 file into your browser's Personal Certificates

# change ownership of sudo-created files to your user
sudo chown user:group *
# add support to access local application by fqdn
sudo echo "127.0.0.1       homeoffice.com" >> /etc/hosts



这是我用来尝试实现此功能的代码。

from BaseHTTPServer import BaseHTTPRequestHandler
import BaseHTTPServer, SimpleHTTPServer
import ssl
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.backends import default_backend

class CustomHandler(BaseHTTPRequestHandler):
    def do_HEAD(self):
        self.send_response(200)
        self.send_header('Content-Type', 'text/html')
        self.end_headers()
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-Type', 'text/html')
        self.end_headers()
    # Need x509.Certificate here instead of dict
        print(self.connection.getpeercert())
    that = x509.load_der_x509_certificate(self.connection.getpeercert(True), default_backend())
    print(that.issuer.rfc4514_string())
    print(that.subject.rfc4514_string())
        self.wfile.write(open("index.html", "r"))
    def do_POST(self):
        cert_dict = self.connection.getpeercert()
        # Need x509.Certificate here instead of dict
        print(type(cert_dict))
        print(cert_dict)

httpd = BaseHTTPServer.HTTPServer(('homeoffice.com', 4443), CustomHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='./server.key', certfile='./server.pem', server_side=True, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1_2, ca_certs='./ca.pem', do_handshake_on_connect=True, suppress_ragged_eofs=True)
httpd.serve_forever()


我希望self.connection.getpeercert()返回一个x509.Certificate对象与一个字典对象。我宁愿使用已经存在的类,也不愿编写自定义代码来解析字典。

更新:研究发现链接对我有帮助...


ssl.SSLSocket
BaseHTTPServer.BaseHTTPRequestHandler
cryptography.x509.Certificate
cryptography.x509.oid modules
cryptography.x509.load_der_x509_certificate()
cryptography.x509.Name.rfc4514_string()

最佳答案

您可以尝试PyOpenSSL。

x509_cert = OpenSSL.crypto.load_certificate(
    OpenSSL.crypto.FILETYPE_ASN1, self.connection.getpeercert(True)
)

关于python - 如何从BaseHTTPRequestHandler python获取x509.Certificate,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56399023/

10-11 19:16