Domanda

Sto cercando di scrivere un'applicazione client-server generico che sarà in grado di scambiare dati tra i server. Ho letto su un bel paio di documenti OpenSSL, e ho messa a punto con successo il mio CA e ha creato un CERT (e la chiave privata) a scopo di test.

mi sono bloccato con Python 2.3, quindi non posso usare la libreria standard "SSL". Invece, mi sono bloccato con pyOpenSSL, che non sembra male, ma non ci sono molti documenti là fuori su di esso.

La mia domanda non è davvero di farlo funzionare. Sono più confuso circa i certificati e dove devono andare.

Ecco le mie due programmi che do di lavoro:

Server:

#!/bin/env python

from OpenSSL import SSL
import socket
import pickle

def verify_cb(conn, cert, errnum, depth, ok):
    print('Got cert: %s' % cert.get_subject())
    return ok


ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)

# ??????
ctx.use_privatekey_file('./Dmgr-key.pem')
ctx.use_certificate_file('Dmgr-cert.pem')
# ??????
ctx.load_verify_locations('./CAcert.pem')

server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))

server.bind(('', 50000))
server.listen(3)

a, b = server.accept()

c = a.recv(1024)
print(c)

Cliente:

from OpenSSL import SSL
import socket
import pickle


def verify_cb(conn, cert, errnum, depth, ok):
    print('Got cert: %s' % cert.get_subject())
    return ok

ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb)

# ??????????
ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')
# ?????????
ctx.load_verify_locations('/home/justin/code/work/CA/CAcert.pem')

sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect(('10.0.0.3', 50000))

a = Tester(2, 2)
b = pickle.dumps(a)
sock.send("Hello, world")

sock.flush()
sock.send(b)
sock.shutdown()
sock.close()

Ho trovato queste informazioni da ftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL -examples-0.6-2.i586.rpm che contiene alcuni script di esempio.

Come si può capire, non riesco a capire pienamente le sezioni tra il "# ????????". Non capisco il motivo per cui il certificato e la chiave privata sono necessari sia sul client e server. Non sono sicuro dove ciascuno dovrebbe andare, ma non dovrei solo bisogno di distribuire una parte della chiave (probabilmente la parte pubblica)? Essa mina lo scopo di avere chiavi asimmetriche se hai ancora bisogno sia su ogni server, giusto?

Ho cercato alternando la rimozione o la pkey o CERT su entrambi i box, e ottengo il seguente errore, non importa quale rimuovo:

  

OpenSSL.SSL.Error: [( 'routine SSL', 'SSL3_READ_BYTES', 'avviso SSLv3 mancata stretta di mano'), ( 'routine SSL', 'SSL3_WRITE_BYTES', 'fallimento ssl stretta di mano')]

Qualcuno potrebbe spiegare se questo è il comportamento previsto per SSL. Ho davvero bisogno per distribuire la chiave privata e il CERT pubblica a tutti i miei clienti? Sto cercando di evitare eventuali problemi di sicurezza enormi, e che perde le chiavi private tenderebbero ad essere un grande ...

Grazie per l'aiuto!

=============================================== ===================

Grazie a caf per avermi aiutato a capire il problema. Sulla base della sua raccomandazione, ho creato due nuove coppie di certificati: astronauta e dmgr. Ho poi messo entrambe le parti "Spaceman" (chiave, CERT) nel programma client, e lo stesso per i tasti "dmgr".

In sostanza, solo le seguenti due righe in Client cambia, anche se c'era pima di lavoro con openssl sul lato.

ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')

Versione corretta:

ctx.use_privatekey_file('/home/justin/code/work/CA/private/spaceman-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/spacemancert.pem')
È stato utile?

Soluzione

In una transazione SSL, ogni lato può presentare un certificato per verificarne l'identità verso l'altro lato. Per fare questo, ha bisogno di avere la chiave privata corrispondente al certificato. Questi sono destinati ad essere due diversi i certificati, in modo da ogni lato avrà due chiavi private diverse.

Questo / coppia di chiave privata del certificato è quello che si sta impostando con use_privatekey_file() e use_certificate_file(). Questo dovrebbe essere un diverso il certificato / coppia di chiavi sul server e il client.

Nel verificare il certificato di coetanei, è quindi necessario controllare:

  • che il certificato è valida (cioè, firmato da una CA che vi fidate per questa applicazione, non è scaduto, non revocato); e
  • Corrisponde al peer che si pensare entrato in contatto con (che è, il certificato corrisponde l'identità che i crediti pari). Questa identità è memorizzato all'interno del campo SubjectName del certificato, ed è applicazione specifica come mappare questo ad un'identità tra pari (che potrebbe essere un nome utente, un nome DNS, o altro).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top