Python中的客户端证书和相互身份验证

时间:2015-05-11 05:19:44

标签: python ssl openssl twisted

我正在尝试使用正确的密钥身份验证进行基于Use TLS and Python for authentication的设置。

在尝试设置正确的ssl证书几天后,我收到此错误。

[Failure instance: Traceback: <class 'OpenSSL.SSL.Error'>: [('SSL routines', 'SSL3_GET_CLIENT_CERTIFICATE', 'no certificate returned')]
/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py:614:_doReadOrWrite
/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py:215:doRead
/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py:221:_dataReceived
/usr/lib/python2.7/dist-packages/twisted/protocols/tls.py:419:dataReceived
--- <exception caught here> ---
/usr/lib/python2.7/dist-packages/twisted/protocols/tls.py:358:_flushReceiveBIO
]

从服务器输出:

def connectionLost(self, reason):
        print reason

我不确定在生成证书时我出错了。

这是我创建证书颁发机构的代码

##------------------------------ Creating CA -------------------------------##
cd /etc/ssl
mkdir CA
cd CA

## Make storage dirs
mkdir certs crl newcerts private

## fix permissions and create directories
chmod 700 private
touch index.txt
echo 1000 > serial

## Create a private key
openssl genrsa -aes256 -out /etc/ssl/CA/private/ca.key.pem 4096
## pass = nill
##/etc/ssl/CA/private/ca.key.pem

chmod 400 /etc/ssl/CA/private/ca.key.pem

## change stuff in ssl config file
nano /etc/ssl/openssl.cnf
###
dir             = /etc/ssl/CA           # Where everything is kept
## Left out
##keyUsage = nonRepudiation, digitalSignature, keyEncipherment
####


##Self sign CA's certificate
openssl req -new -x509 -days 3650 -key /etc/ssl/CA/private/ca.key.pem -sha256 -extensions v3_ca -out /etc/ssl/CA/certs/ca.cert.pem


###
US
AZ
AZ
Nameless CA
Certificate Authority
Nameless CA
3Nameless22222@Nameless.com
###

## This is the CA's public key
chmod 444 /etc/ssl/CA/certs/ca.cert.pem
cp /etc/ssl/CA/certs/ca.cert.pem /etc/ssl/certs/ca.cert.pem

## Join ca.cert.pem and ca.key.pem into a file named ca.private.cert.pem
## in /etc/ssl/private/ca.private.cert.pem
##---------------------------- Creating CA END -----------------------------##

服务器密钥

##-------------------------- Creating Server Key ---------------------------##
cd /etc/ssl/CA

##Create private key for server
openssl genrsa -out private/servermain.key.pem 4096
chmod 400 private/servermain.key.pem


##Create signing request
cd /etc/ssl/CA
openssl req -sha256 -new -key private/servermain.key.pem \
    -out certs/servermain.csr.pem


Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:AZ
Locality Name (eg, city) [Default City]:AZ
Organization Name (eg, company) [Default Company Ltd]:Nameless CA
Organizational Unit Name (eg, section) []:Certificate Authority
Common Name (eg, your name or your server's hostname) []:mainserver
Email Address []:3Nameless22222@Nameless.com
###

cd /etc/ssl/CA

## Sign servers signing request
openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem \
    -extensions usr_cert -notext -md sha256 \
    -in certs/servermain.csr.pem -out certs/servermain.cert.pem
chmod 444 /etc/ssl/CA/certs/nill.cert.pem

## Join servermain.cert.pem and servermain.key.pem into a file named
## server.pem in /etc/ssl/private/server.pem

##------------------------ Creating Server Key End -------------------------##

客户端证书创建:

##------------------------ Create New Client Certs -------------------------##
from twisted.python.filepath import FilePath
from twisted.internet.ssl import PrivateCertificate, KeyPair, DN
def getCAPrivateCert():
    #path to a private key
    ## needs to be the path to a CA's private key for signing
    privatePath = FilePath(b"/etc/ssl/private/cacert.pem")
    if privatePath.exists():
        return PrivateCertificate.loadPEM(privatePath.getContent())
    else:
        print "CRASH TIME"

def clientCertFor(name):
    signingCert = getCAPrivateCert()
    clientKey = KeyPair.generate(size=4096)
    csr = clientKey.requestObject(DN(CN=name), "sha1")
    clientCert = signingCert.signRequestObject(
        csr, serialNumber=1, digestAlgorithm="sha1")
    return PrivateCertificate.fromCertificateAndKeyPair(clientCert, clientKey)

if __name__ == '__main__':
    import sys
    name = sys.argv[1]
    pem = clientCertFor(name.encode("utf-8")).dumpPEM()
    FilePath(name.encode("utf-8") + b".client.private.pem").setContent(pem)
##---------------------- Create New Client Certs End -----------------------##

创建服务器

##--------------------------------- Server ---------------------------------##
## Note: server.pem is the servers certificate joined with the public key
## servermain.key.pem
## servermain.cert.pem
## ca.cert.pem is the CA's public certificate
from twisted.python.filepath import FilePath
from twisted.internet.endpoints import SSL4ServerEndpoint
from twisted.internet.ssl import PrivateCertificate, Certificate
from twisted.internet.defer import Deferred
from twisted.internet.task import react
from twisted.internet.protocol import Protocol, Factory
CERTFILE = "/etc/ssl/certs/ca.cert.pem"
SERVERCERT = "/etc/ssl/private/server.pem"

class ReportWhichClient(Protocol):
    def dataReceived(self, data):
        print "****************** NEW PEER REQUEST ******************"

        ## Get peer cert id
        peerCertificate = Certificate.peerFromTransport(self.transport)
        userkey = peerCertificate.getSubject().commonName.decode('utf-8')
        print userkey

    def connectionMade(self):
        print "connected"

    def connectionLost(self, reason):
        print reason

def main(reactor):
    print "react"

    #Path to CA public key
    cacert = FilePath(CERTFILE).getContent()

    #Path to Server private key
    pemBytes = FilePath(SERVERCERT).getContent()

    ## should be ca's public key from sudo mv cacert.pem /etc/ssl/certs/?
    certificateAuthority = Certificate.loadPEM(pemBytes)
    myCertificate = PrivateCertificate.loadPEM(pemBytes)
    serverEndpoint = SSL4ServerEndpoint(reactor, 4321, myCertificate.options(certificateAuthority))
    serverEndpoint.listen(Factory.forProtocol(ReportWhichClient))
    return Deferred()

react(main, [])
##------------------------------- Server End -------------------------------##

客户:

##---------------------------- Client function -----------------------------##
##Main key reading class
@inlineCallbacks
def main(reactor, name):
    ## Client private key
    pem = FilePath(name.encode("client1.key.pem").getContent()
    #CA public key
    caPem = FilePath(b"ca.cert.pem").getContent()

    clientEndpoint = SSL4ClientEndpoint(
        reactor, u"localhost", 4321,
        optionsForClientTLS(u"Nameless CA", Certificate.loadPEM(caPem),
                            PrivateCertificate.loadPEM(pem)),
    )

    proto = yield clientEndpoint.connect(Factory.forProtocol(SendAnyData))
    yield proto.deferred

import sys
react(main, sys.argv[1:])
##-------------------------- Client function End ---------------------------##

0 个答案:

没有答案