(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.