2014-04-24 21 views
15

Ho già implementato la comunicazione SSL in cui l'applicazione client verifica l'identità dell'applicazione server SSL utilizzando il pallone. Ora voglio un'applicazione server SSL per verificare l'identità dell'applicazione client SSL. È possibile con la fiaschetta? Come posso verificare il certificato del cliente? Durante il primo handshake il client invia il CSR e in risposta sto rinviando il certificato firmato dal certificato CA autofirmato.Autenticazione ssl a due vie per matraccio

Ma non sono ancora chiaro come il client verrà verificato dal server durante la prossima comunicazione. Esiste una richiamata per la verifica del certificato. Il collegamento su Google groups dice che non è possibile avere l'autenticazione ssl su Flask. per fare questo è necessario utilizzare webserver come apache, ngnix. È questo l'unico modo per autenticare il cliente?

C'è ancora una cosa che voglio ottenere che ho bisogno di identificare ogni cliente in base al loro certificato. è possibile anche con la fiaschetta.

mia domanda potrebbe essere ingenua come io non sono ancora molto familiare a pallone

+0

Perché è necessario eseguire l'autenticazione dall'altra parte? A meno che il client non stia ascoltando le connessioni non dovrebbe essere necessario. –

+0

@ sshanshank124 Vorrei autenticare ciascun client in base al certificato client ed elaborare la sua richiesta di conseguenza – nishi

+2

TLS/SSL è una funzionalità che fa parte del server web. La tua domanda implica che stai utilizzando il server di sviluppo di Flask invece di un server di produzione per eseguire la tua app. Questa è probabilmente una cattiva idea. Dai un'occhiata a http://flask.pocoo.org/docs/0.10/deploying/ –

risposta

6

responsabilità

Prima di iniziare vorrei far notare il commento di @Emanuel Ey. Che vorresti considerare se questo è stato fatto prima su un server di produzione o di sviluppo. Per esempio; se si utilizza Apache WebServer, il componente HTTPS può essere eseguito da Apache. L'unica cosa che farebbe diversamente è passare attraverso i dettagli del certificato come opzioni e l'app del server dovrebbe quindi verificare il numero di serie all'interno dell'app stessa.

è possibile

Ma il modo in cui è possibile non è considerata buona pratica di programmazione. Sfortunatamente, non è accessibile da flask.request e non è possibile con il pacchetto Flask. Tuttavia, Flask usa Werkzeug ed è possibile correggendo il pacchetto werkzeug.serving dove scriverà il tuo codice principale. Non è raccomandato perché potresti voler aggiornare Flask o Werkzeug in un secondo momento e la tua patch potrebbe rompersi e necessitare di essere riprogrammata. cioè da 0,9 a 1,0.

Fornisce una soluzione senza utilizzare un server web. Ma raccomanderei la combinazione di server Web/variabile di ambiente. È una pratica più pulita e relativamente buona.

Ho eseguito alcuni test per verificare se è facile da implementare. Sono stato in grado di confermare che questo metodo può funzionare utilizzando l'ultimo codice di sviluppo di sviluppo 'Werkzeug-0.10_devdev_20141223-py2.7'.

Probabilmente vorrete verificare il numero di serie (numero seme) trovato in ciascun certificato (e forse anche qualche altra variabile). Come forse saprai, la serie è unica per ogni certificato e viene determinata durante il processo di generazione del certificato da parte tua sul lato server. Aiuta a memorizzare questo insieme al record del cliente e le informazioni sul certificato (se necessario) al fine di verificare in seguito il numero di serie del certificato del cliente. Nota: potrebbe richiedere delle modifiche tra esadecimale e decimale base 10.

Werkzeug dev_2014122

Quello che ho fatto è stato quello di aggiungere le seguenti opzioni alla chiamata werkzeug.serving.BaseWSGIServer.__init__-wrap_socket().

Utilizzare questi; server_side=True, ca_certs= '/etc/apache2/ssl/ca.pem', cert_reqs=ssl.CERT_REQUIRED

  • ca_certs: Usare questo per verificare contro, questo è il CERT CA utilizzato per generare i certificati client)
  • ssl.CERT_REQUIRED: richiedere la verifica del certificato client contro ca_certs

Nota: Se il certificato client non supera la verifica iniziale, non sarà possibile recuperare il certificato client. Sarà None.

Poi nella mia classe di test Flask ho patchato verify_request dove

def verify_request(self, request, client_address): 

cert = request.getpeercert(True) 
raw = decoder.decode(cert)[0] 
print "Serial Number of your certificate is: % " % str(raw[0][1]) 
# todo: do checks & if serial no is ok then return true 
return True 

werkzeug.serving.BaseWSGIServer.verify_request = verify_request 

Questo si è rivelato è possibile ma probabilmente vuole indagare i gestori delle richieste della classe HTTPServer che il BaseWSGIServer eredita da trovare un modo migliore per richiamare o ignorare.

Werkzeug 0.9.x

Se si utilizza Werkzeug 0.9.x Sto assumendo che si sta utilizzando l'importazione from OpenSSL import SSL. vedere lo snippet di codice here. Non ho provato questo.

Alcune delle chiamate a cui potresti essere interessato per questa versione sarebbero; - Context.set_verify(mode, callback) - Connection.get_peer_certificate()

Chiarimento

Quello che non capisco è il vostro riferimento all'invio di una CSR durante la prima stretta di mano. Se questo è il tuo processo di generazione di certificati client, potresti voler ripensare a come lo fai nel contesto del tuo sistema e dell'ambiente. Se potessi avere qualche informazione in più potrei commentare ulteriormente ..

Inoltre, "stretta di mano" in un contesto SSL/TLS generalmente si riferisce all'azione di creare la connessione protetta in primo luogo utilizzando un certificato esistente. Immediatamente dopo l'handshaking, parlando liberamente, viene stabilita una connessione.

+0

Come ottengo l'oggetto Connection? È accessibile dall'oggetto di richiesta del pallone? –

+0

Ho testato una patch di scimmia per la dimostrazione del concetto e modificato la risposta. Non è una buona pratica, ma mostra che è possibile SE AVETE BISOGNO. Si prega di notare le differenze di Werkzeug 0.9 e 1.0 con il pacchetto SSL. – Ross

+0

Grazie per la risposta. Vorrei rivisitare questo e controllare se questo funziona nel mio caso – nishi

Problemi correlati