2015-06-02 13 views
10

Non riesco a far funzionare correttamente l'handshake.Le richieste Python inviano il certificato come stringa

cert = 'path/to/cert_file.pem' 
url = 'https://example.com/api' 

requests.get(url, cert=cert, verify=True) 

Questo va bene quando lo uso a livello locale dove ho il file fisicamente. Ospitiamo la nostra applicazione su heroku e utilizziamo environmentvariables.

Il modulo delle richieste sembra non accettare i certificati come stringhe. per esempio.

$ export CERTIFICATE="long-list-of-characters" 

requests.get(url, cert=get_env('CERTIFICATE'), verify=True) 

Ho anche provato qualcosa di simile:

cert = tempfile.NamedTemporaryFile() 
cert.write(CERTIFICATE) 
cert.seek(0) 
requests.get(url, cert=cert.name, verify=True) 

Prima di tutto, funziona in locale ma non su Heroku. Ad ogni modo, non sembra una soluzione solida. Ottengo un errore di handshake SSL.

Qualche suggerimento?

+1

Possibile duplicato di [Come aprire il socket ssl utilizzando il certificato memorizzato in variabili stringa in python] (http://stackoverflow.com/questions/12336239/how -to-open-ssl-socket-using-certificato-memorizzato-in-string-variabili-in-python) –

+0

@Gelbander, che ha firmato il file cert_file.pem? È autofirmato dall'autorità di certificazione personalizzata/inhouse root? Hai provato a caricare il tuo file pem su Heroku, solo per essere sicuro che funzioni passando il percorso completo di pem in Heroku? –

+0

Inoltre non sono sicuro che l'uso delle variabili env sia il modo preferito. Probabilmente è meglio usare "heroku certs: aggiungi server.crt server.key" –

risposta

1

Come per la documentazione requests:

La chiave privata per il certificato locale deve essere in chiaro. Attualmente, Requests non supporta l'uso di chiavi crittografate.

Si può [anche] specificare un cert locale da utilizzare come certificato lato client, come un unico file (contenente la chiave privata e il certificato) o come una tupla di percorso di due file:

requests.get('https://kennethreitz.com', cert=('/path/client.cert', '/path/client.key')) 

È necessario includere il percorso per la chiave pubblica e privata ... oppure è possibile includere il percorso di un singolo file che contiene entrambi.

1

La risposta di Vasili è tecnicamente corretta, sebbene di per sé non risponda alla tua domanda. Il file di chiavi, in verità, deve essere non criptato per cominciare.

Io stesso ho appena risolto una situazione come la tua. Eri sulla strada giusta; tutto quello che doveva fare era

1. Passo delete=False-NamedTemporaryFile(), in modo che il file non saranno eliminati dopo aver chiamato close()

2.close() il tempfile prima di utilizzarlo, quindi sarebbe salvato

Si noti che questa è una cosa molto pericolosa da fare. delete=False, come ho capito, fa sì che il file rimanga sul disco anche dopo aver cancellato il riferimento ad esso. Pertanto, per eliminare il file, è necessario chiamare manualmente os.unlink(tmpfile.name).

Fare questo con i certificati è un enorme rischio per la sicurezza: è necessario assicurarsi che la stringa con il certificato sia protetta e nascosta e nessuno abbia accesso al server.

Tuttavia, è piuttosto una pratica utile in caso di, ad esempio, la gestione applicazione sia su un server di Heroku come un ambiente di prova e un'immagine Docker costruita nel cloud, in cui COPY direttive non sono un'opzione in.È anche decisamente meglio che archiviare il file nel tuo repository git: D