Autenticazione del certificato client SSL

9

È possibile creare un programma che utilizzi l'autenticazione del certificato client con solo la chiave pubblica e privata (non ho generato alcun certificato, ho solo la chiave pubblica e privata).

Semplicemente, voglio fare l'autenticazione sul server con l'autenticazione del certificato client. Ma è difficile rendere il certificato client programmaticamente.

Voglio rendere l'autenticazione del certificato client con solo la chiave pubblica e privata (ho solo la chiave pubblica e privata, nessun certificato).

È possibile inviare una chiave pubblica del server invece del certificato client per l'autenticazione del certificato client?

    
posta Taleh Ibrahimli 03.08.2013 - 21:32
fonte

4 risposte

11

I certificati sono solo la chiave pubblica con qualche contesto aggiunto. Il nome della chiave, le firme, le linee guida sull'utilizzo, ecc. SSL / TLS dipende in quel contesto. Altrimenti l'host a cui ti connetti non saprà se la chiave appartiene davvero a te o no. Il meccanismo di attendibilità SSL è basato sul concetto di certificati esplicitamente attendibili e quindi sui certificati implicitamente attendibili firmati.

Ma se non stai usando SSL o TLS, la crittografia può ancora accadere senza di essa, ma la fiducia deve avvenire in un modo diverso. SSH ne è un buon esempio: SSH utilizza ancora le chiavi pubbliche e private, ma poiché non esiste una gerarchia di firme, le informazioni aggiunte fornite dai certificati non sarebbero utili, quindi la chiave viene inviata vuota. Invece, il client ti chiede se fidarti o meno della chiave pubblica del server la prima volta che si connette e ogni volta dopo controlla se la chiave pubblica corrisponde a ciò che ha visto l'ultima volta. Ciò può accadere perché SSH non utilizza SSL o TLS per la sua crittografia.

Ma se si utilizza il protocollo SSL, il protocollo stabilisce che la chiave pubblica deve essere presentata con il contesto aggiunto del certificato. Cioè, il certificato è il contenitore in cui deve essere inserita la chiave pubblica per SSL per utilizzarlo.

Se hai la chiave privata, è banale creare un certificato autofirmato usando uno strumento come OpenSSL.

    
risposta data 03.08.2013 - 21:45
fonte
8

SSL / TLS supporta l'autenticazione del client con un certificato. Quello che succede veramente internamente è questo:

  • Il server richiede un "certificato client" tramite un messaggio CertificateRequest .
  • Il client invia il certificato come messaggio Certificate e calcola anche una firma (utilizzando la sua chiave privata) su tutti i messaggi precedenti nell'handshake; la firma viene inviata come messaggio CertificateVerify .
  • Il server in qualche modo ottiene la chiave pubblica del client (normalmente decodificando il certificato client come X .509 certificato, convalidandolo in modo X.509 e quindi estraendo la chiave pubblica da esso) e lo utilizza per verificare la firma dal client.

Tuttavia, nel protocollo stesso, i certificati vengono scambiati come blocchi opachi di byte; ogni "certificato" viene inviato con un'intestazione a 3 byte che ne specifica la lunghezza. Quindi, se controlli sia il codice server che quello client, allora spetta completamente a te decidere come interpretare questi blocchi di byte. Non è necessario inviare un certificato X.509 . Potresti inviare un messaggio vuoto, se lo desideri.

I punti importanti rimangono:

  • Affinché l'autenticazione abbia senso, il server deve conoscere con una certa garanzia la chiave pubblica del client. La firma dimostra che il client controlla la chiave privata, ma ciò è utile solo se la chiave pubblica corrispondente è associata in modo non ambiguo a un'identità client nota.

  • La coppia di chiavi deve essere di un tipo adatto per le firme (cioè RSA o DSA, non Diffie-Hellman).

Le implementazioni SSL esistenti potrebbero insistere sul rispetto almeno del formato X.509, nel qual caso devi avvolgere la tua chiave pubblica in una sorta di certificato X.509 autofirmato, che è relativamente facile da programmare con alcune librerie come OpenSSL .

C'è uno standard per sostituire i certificati X.509 in SSL con le chiavi pubbliche OpenPGP, dimostrando l'agilità del formato inerente a SSL.

    
risposta data 04.08.2013 - 15:44
fonte
2

(Questo è basato su la mia risposta alla stessa domanda su SO . Spesso è meglio chiedere su una sola SE sito).

Il protocollo TLS consente solo lo scambio di certificati, non chiavi pubbliche non elaborate. Anche "chiavi PGP" (se si desidera sostituire X.509 con OpenPGP per l'autenticazione in TLS , che è molto meno supportato ) sono infatti certificati (sono la combinazione firmata di una chiave pubblica e un insieme di identificatori e attributi).

Come dice Thomas, potresti definire il tuo tipo di certificato e renderlo una semplice chiave pubblica (anche se non sono sicuro che possano ancora essere chiamati "certificati" tecnicamente).

Da un punto di vista pratico, dovresti essere in grado di ottenere ciò che ti serve utilizzando gli stack SSL / TLS esistenti e modificare il modo in cui gestiscono i certificati X.509 di verifica, con cautela . Infatti, la maggior parte degli stack SSL / TLS espongono la verifica dei certificati X.509 attraverso le loro API, ma pochi consentono altri tipi di certificati (ad esempio OpenPGP) o consentono di personalizzare facilmente il proprio codice. La personalizzazione per certificati non X.509 potrebbe essere abbastanza difficile, potrebbe portare a ulteriori bug se si è nuovi all'implementazione SSL / TLS e sarebbe anche difficile da implementare in pratica, poiché tutti i potenziali clienti avrebbero anche bisogno di supportare le personalizzazioni .

Puoi eseguire l'autenticazione del client utilizzando certificati X.509 del client autofirmati e fare affidamento sulle loro chiavi pubbliche ( ma dovrai verificare questa chiave pubblica contro qualcosa che il tuo server già conosce, come un elenco noto ). È necessario comprendere le implicazioni di sicurezza per l'implementazione di questo primo. Questo non è lo stesso problema dei certificati server autofirmati. (Suggerirei di mantenere un approccio più tradizionale alla verifica del certificato del server.)

Puoi fare in modo che il client invii un certificato autofirmato (possibilmente utilizzando alcuni trucchi riguardanti l'elenco di CA pubblicizzato dal server ) e eseguire la verifica nello stack TLS o più tardi nell'applicazione.

Si noti che molti contenitori di applicazioni (ad esempio Tomcat / Jetty in Java) si aspettano che il livello SSL / TLS verifichi il certificato client. Quindi, se si salta l'autenticazione lì (e si preferisce farlo più tardi all'interno del contenitore o come parte dell'applicazione), molti framework applicativi verranno confusi. Devi fare molta attenzione per assicurarti che l'autenticazione sia effettivamente eseguita da qualche parte prima di eseguire qualsiasi azione che richiede l'autenticazione nella tua applicazione.

Ad esempio, può essere OK avere un gestore di fiducia che permetta a qualsiasi certificato client attraverso in Tomcat / Jetty, ma non si può fare affidamento sull'attributo di richiesta javax.servlet.request.X509Certificate per essere verificato in alcun modo (che la maggior parte dei framework altrimenti si aspetterebbe). Dovresti implementare alcune logiche di verifica all'interno della tua applicazione: ad esempio, avere un filtro prima di qualsiasi funzione autenticata che confronta la chiave pubblica in questo certificato client con il tuo elenco noto di chiavi pubbliche (o comunque vuoi abbinare la chiave pubblica a un identificatore). In alternativa, puoi eseguire questa verifica anche nel tuo gestore di fiducia personalizzato (in Java), questo richiederà meno lavoro all'interno delle applicazioni.

Potresti fare qualcosa di simile in un setup Apache Httpd + PHP (per esempio), usando SSLVerifyClient optional_no_ca . Ancora una volta, la tua applicazione PHP non ha potuto fare affidamento sul fatto che il certificato sia stato verificato, quindi dovresti implementarlo anche in questo caso.

Non fare nulla se non comprendi in quale fase sono state verificate le informazioni sul certificato.

    
risposta data 08.08.2013 - 15:08
fonte
0

oltre al nostro caro amico, tylerl

dovresti conoscere il comando linux di OpenSSL e avere una buona abilità di programmazione in PHP o perl. (specialmente PHP) ecco alcune buone guide a riguardo: 1- link e 2-openssl. org devi avere una profonda conoscenza del comando openssl e delle sue funzioni.

alla fine: (la tua domanda) È possibile inviare la chiave pubblica del server anziché il certificato client per l'autenticazione del certificato client? no, perché potresti dimenticare il protocollo TLS Handshake che mostra passo per passo client-server l'autenticazione e lo scambio di chiavi. link

    
risposta data 03.08.2013 - 23:46
fonte

Leggi altre domande sui tag