Hier ein einfacher SSL-Client:
Code: Alles auswählen
from OpenSSL import SSL, crypto
import socket
HOST = "www.example.com"
PORT = 443
PAGE = "/index.html"
def verify_cb(conn, cert, errnum, depth, ok):
print "Got certificate: %s" % cert.get_subject()
print "Issued by: %s" % cert.get_issuer()
return ok
keystore = crypto.load_pkcs12(open("userkey.p12").read(), "geheim")
# Initialise SSL context:
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb) # Demand a server certificate
ctx.load_verify_locations("server-ca-cert.pem")
ctx.use_privatekey(keystore.get_privatekey())
ctx.use_certificate(keystore.get_certificate())
# Set up client:
sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect((HOST, PORT))
sock.write("GET %s HTTP/1.0\nHost: %s\n\n" % (PAGE, HOST))
# Read response:
while True:
try:
print sock.recv(4096)
except SSL.ZeroReturnError:
break
In Zeile 17 wird angegeben, dass das Zertifikat vom Server angefragt und gecheckt werden soll. verify_cb gibt eine Callack-Funktion an, die nach jedem Zertifikats-Check (fuer jedes Zertifikat in der Certificate Chain) ausgefuehrt wird, Zeilen 8 bis 11.
Zeile 18 laedt das CA-Zertifikat, mit dem das Server-Zertifkat geprueft werden soll.
Fuer viele https-Verbindungen reichen diese Angaben schon aus; benoetigt man jedoch ein User-Zertifikat, um sich beim Server zu authentifizieren, so muss man den privaten und oeffentlichen Schluessel laden, siehe Zeile 19 und 20. Diese beiden Funktionen nehmen nur das pem-Format. Meist liegt das private/public key pair in einen pkcs12-Format vor, solch einen Keystore kann man mit dem crypto-Modul von pyopenssl laden (Zeile 12) und sich dann die beiden Schluessel ins pem-Format umwandeln lassen.
Der ssl-Socket, der in Zeile 23 erzeugt wird, laesst sich jetzt wie ein ganz normaler Socket verwenden.
Ein SSL-Server funktioniert ganz genau so, nur dass man ab Zeile 24 die gewoehnlichen Befehle fuer einen Server-Socket absetzt:
Code: Alles auswählen
# Set up sever:
sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen(1)
print "Waiting for connections."
#Wait for clients to connect:
(conn, address) = sock.accept()
print "Got connection from %s: %s" % address
while True:
try:
print conn.recv(4096)
except SSL.ZeroReturnError:
break
