Estrai certificato smartcard per l'autenticazione da server a server

0

Voglio ottenere dati da un server che accetta solo l'autenticazione del client tramite smartcard e li salviamo sul mio server. Dato che sono molti dati, voglio creare una connessione tra il mio server e questo server di terze parti, ma ho bisogno del certificato dell'utente nella smart card. È impossibile per me estrarre la chiave privata dalla smart card, ovviamente, quindi non so se sia possibile o meno.

Ho abilitato sul mio server Apache l'autenticazione del client in questo modo:

  SSLVerifyClient require
  SSLVerifyDepth 4
  SSLProtocol +TLSv1.1 +TLSv1.2
  SSLOptions +ExportCertData +StdEnvVars
  SSLCACertificateFile /usr/share/ca-certificates/ca-bundle.crt

Dopo che l'utente ha inserito il PIN, con il mio script PHP posso ottenere il certificato in questo modo:

$_SERVER["SSL_CLIENT_CERT"];

Infine cerco di utilizzare questo certificato per firmare la richiesta tramite php cURL in questo modo:

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://ext.processotelematico.giustizia.it/pda/pycons/GLMV/JPW_SICID",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_SSL_VERIFYPEER => true,
  CURLOPT_SSLCERT => $certificate,
  CURLOPT_POSTFIELDS => "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>\r\n  <soapenv:Header>\r\n    <ws:InvocationDomain name=\"JPW\" role=\"AVV\" group=\"9876\" soapenv:mustUnderstand=\"1\" soapenv:actor=\"http://schemas.xmlsoap.org/soap/actor/next\" xmlns:ws=\"http://www.netserv.it/anag/security\" />\r\n  </soapenv:Header>\r\n  <soapenv:Body>\r\n    <sicc:execute xmlns:sicc=\"urn:CONS-ANONIMA-SICC-BE\">\r\n      <sicc:name>RicercaRuoloGenerale</sicc:name>\r\n      <sicc:valueSet>\r\n        <sicc:value name='idUfficio' type='string'>9876</sicc:value>\r\n        <sicc:value name='numero' type='integer'>1</sicc:value>\r\n        <sicc:value name='anno' type='string'>2017</sicc:value>\r\n      </sicc:valueSet>\r\n      <sicc:orderBy>\r\n        <sicc:entry mode='asc' property='IDFASCICOLO' />\r\n      </sicc:orderBy>\r\n    </sicc:execute>\r\n  </soapenv:Body>\r\n</soapenv:Envelope>",
  CURLOPT_HTTPHEADER => array(
    "cache-control: no-cache",
    "content-type: text/xml",
    "x-wasp-user: user-id"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

Ma ho ricevuto questo errore: "impossibile impostare il file della chiave privata:". Quindi, suppongo di avere solo la parte pubblica del certificato. C'è qualcosa che posso fare per accedere da remoto? O è impossibile? So che dovrei usare il codice lato client, come Java Applet, ma, come detto, ci sono molti dati e voglio evitare di scaricarli sul client e caricare di nuovo sul mio server.

UPDATE: Giusto per chiarire il caso d'uso:

  • Il secondo server è un server governativo. Il ministero fornisce i dati dei cittadini dopo il login. Non posso cambiare nulla su questo server, ovviamente.

  • Il governo rilascia le smartcard per l'autenticazione, tramite le autorità di certificazione attendibili. Ho sul mio server i certificati CA, quindi la CA non è un problema (suppongo)

  • La mia app web dovrebbe scaricare, gestire e rappresentare i dati del cittadino in un modo migliore rispetto al server originale

posta zuno 05.07.2017 - 16:43
fonte

2 risposte

0

It's impossible for me extract the private key from the smart card, of course, so I don't know if this is possible or not.

Non è possibile, perché la chiave privata non può essere estratta dalla smartcard.

So, I suppose I have only the public part of the certificate.

Sì, è esattamente questo. Il certificato trasmesso al server dal protocollo SSL / TLS non contiene la chiave privata.

There is something I can do to login remotely?

Il modo comune è che il primo server firma la richiesta con un proprio certificato (che sarà controllato sul secondo server) e passa il certificato client in un'intestazione personalizzata. Costruisci una catena di fiducia in questo modo:

  • il client si autentica sul primo server con il suo certificato firmato da una CA - il primo server si fida della CA e attraverso di essa si fida del certificato client
  • il primo server autentica sul secondo server con un certificato del server. Il secondo server considera attendibile il certificato e quindi si fida del certificato client passato nella richiesta

Dopo la modifica, ciò che descrivi è un attacco MITM serio: vuoi gestire i dati scambiati su una connessione sicura. Se si desidera fare ciò che si desidera, il server sarà in grado di inviare qualsiasi richiesta per conto dell'utente, mentre la richiesta verrebbe autenticata con il certificato utente che diceva diversamente un'autenticazione strong che includeva il non ripudio. Questo è esattamente ciò che i certificati di smartcard impediscono! Il meglio che puoi fare è contattare il ministero per spiegare che vorresti fornire un servizio al di sopra di questi dati e chiedere cosa propongono. Se sono d'accordo, saranno in grado di adattare il sistema di autenticazione per consentire ai fornitori a valore aggiunto, se non lo fanno, temo che il tuo progetto non sarà possibile. E anche con il codice client, dovresti avere conseguenze legali.

    
risposta data 05.07.2017 - 18:52
fonte
0

Ti manca il punto su come funziona SSLVerifyClient (e SSLVerifyDepth ).

Ciò che queste 2 configurazioni fanno è attivare Autenticazione del client TLS , che richiede un certificato pubblico e sfida l'utente a dimostrare come afferma di firmare qualcosa utilizzando il suo certificato privato.

Non è necessario che la chiave privata lasci la smartcard per firmare qualsiasi cosa. Le comuni smartcard forniscono interfacce per le firme crittografiche (guarda PKCS # 11 e C_Sign)

La ripartizione effettiva (semplificata) è:

  • Il server richiede il certificato pubblico del client;
  • Il client invia un certificato pubblico;
  • Sfida problemi con il server;
  • La sfida dei segni del cliente;
  • Il server verifica la firma

Quando la firma è verificata, ciò dimostra che l'utente ha la proprietà della chiave privata per un certificato (senza dover inviare la chiave privata al server). Se il server considera attendibile il firmatario del certificato (o chiunque sia presente nella catena di segni CA fino a SSLVerifyDepth), l'utente può accedere alla pagina.

Come test, prova a utilizzare un SSLCACertificateFile diverso e vedi cosa succede quando provi ad accedere alla pagina (o semplicemente nega l'accesso alla tua smartcard quando il tuo browser ne richiede l'accesso). Se ottieni una pagina 40X, significa che Apache sta consegnando l'autenticazione come previsto.

    
risposta data 05.07.2017 - 20:43
fonte

Leggi altre domande sui tag