2010-02-10 45 views
19

Attualmente, ho implementato con successo la sicurezza dell'autenticazione reciproca fintanto che il client accede al sito Web utilizzando un browser Web, poiché i browser si occupano di tutti gli scambi di certificati. Ora ho bisogno di creare un'interfaccia sicura con la quale gli utenti possano accedere ai servizi Web su HTTPS, utilizzando l'autenticazione reciproca richiesta dal server.Autenticazione reciproca con servizi Web

Prima di tutto, ci sono risorse che qualcuno sa di ciò che può aiutarmi con questo? Ho cercato per un po 'di tempo e non ho trovato nulla. Qualche altro consiglio che qualcuno può darmi su come fare per questo?

In secondo luogo, penso che il mio maggiore ostacolo sia la mia mancanza di comprensione su come gestire i certificati. Come negoziare accettando la chiave del server e presentando la mia chiave al server? Questo è in Java.

risposta

1

Una semplice ricetta viene fornita in this blog entry.

Ma penso che la risposta reale possa dipendere dalle API Java che si stanno utilizzando per implementare le interazioni HTTP lato client. Ad esempio, sembra che tu voglia fare le cose a bit differently usando JAX-RPC.

6

Se la libreria di servizi Web utilizza la classe standard java.net.URL come client HTTP, è possibile impostare alcuni system properties e l'autenticazione bidirezionale verrà gestita dal supporto HTTPS integrato.

Il necessary properties sono:

  • javax.net.ssl.trustStore: contiene i certificati radice CA
  • javax.net.ssl.keyStore: Contiene certificato client e chiave privata
  • javax.net.ssl.keyStorePassword: La password di protezione della chiave privata

Questi client le impostazioni diventano predefinite per tutte le connessioni SSL dal processo. Se si desidera un controllo più preciso, è necessario impostare il proprio SSLContext. Se ciò è possibile con il tuo runtime webservice dipende da quale runtime hai scelto.

11

per l'autenticazione reciproca con SSL (aka due vie SSL) al di fuori di un browser, è necessario ... Beh, in realtà, vediamo quello che serve per una via SSL prima:

  1. A server di chiavi
  2. Un client trustStore

l'archivio chiavi server contiene il certificato (possibilmente auto-firmato) del server e la chiave privata. Questo archivio viene utilizzato dal server per firmare i messaggi e restituire le credenziali al client.

Il truststore del client contiene il certificato del server (autofirmato) (estratto dal keystore del server in un certificato autonomo, senza la chiave privata del server). È necessario se il certificato non è firmato da una CA attendibile per la quale si dispone già di un certificato nel truststore in dotazione con JRE. Questo passaggio consente di creare una catena di fiducia.

Con questo, è possibile implementare SSL unidirezionale (il caso d'uso tradizionale).

Per implementare due vie SSL, è necessario effettuare questa configurazione "simmetrica", così avremo bisogno di aggiungere:

  1. Una chiavi cliente
  2. Un server truststore

Il Il keystore del client contiene il certificato del client (possibilmente autofirmato) e la chiave privata. Questo archivio viene utilizzato dal client per lo stesso scopo del keystore del server, ad esempio per inviare le credenziali del client al server durante l'handshake di autenticazione reciproca TLS.

Il truststore del server contiene i certificati autonomi dei client (autofirmati) (estratti dal keystore dei client in certificati stand-alone, senza chiave privata dei client). Questo è richiesto per gli stessi identici motivi precedentemente menzionati.

Alcune risorse per aiutare a generare tutta questa roba e ad attuare le soluzioni finali:

+3

Anche se hai spiegato il concetto di autenticazione reciproca abbastanza bene, i collegamenti non sono molto utili a tutti. La sicurezza del servizio web Java è cambiata un bel po 'dal 2006! :) – Catchwa

14

ho trascorso un lungo tempo su questo ma finalmente ho trovato un esempio che attua l'alleato funziona. È basato su Glassfish e Netbeans, ma credo che potresti farlo funzionare in altri ambienti (ad esempio, Eclipse e Tomcat) se ci hai giocato.

http://java.sun.com/webservices/reference/tutorials/wsit/doc/WSIT_Security9.html#wp162511

Il problema che ho trovato però è quando si desidera utilizzare i propri certificati, non quelli che vengono pre-installato con pesci vetro.

Nota: non sono un esperto di sicurezza. Non distribuire questo in un ambiente di produzione!

Per fare questo sto usando NetBeans 6.9, JDK 1.6, GlassFish 3.0.1 e OpenSSL v1.0 (sto usando i binari Win32 non ufficiali)

# Create the CA 
mkdir ca server client 
cd ca 
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.pem 
echo 02 > serial.txt 
cd .. 

# Creating the Server Keystore 

openssl req -days 3650 -newkey rsa:1024 -keyout server/server.key -out server/server.req 
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in server/server.req -out server/server.crt 
openssl pkcs12 -export -inkey server/server.key -in server/server.crt -out server/server.p12 -name server 
keytool -importkeystore -destkeystore server/server.jks -deststoretype jks -srckeystore server/server.p12 -srcstoretype pkcs12 
keytool -exportcert -alias server -keystore server/server.jks -file server/server.cer 

# Create the Client Keystore 

openssl req -days 3650 -newkey rsa:1024 -keyout client/client1.key -out client/client1.req 
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in client/client1.req -out client/client1.crt 
openssl pkcs12 -export -inkey client/client1.key -in client/client1.crt -out client/client1.p12 -name client1 
keytool -importkeystore -destkeystore client/client1.jks -deststoretype jks -srckeystore client/client1.p12 -srcstoretype pkcs12 
keytool -exportcert -alias client1 -keystore client/client1.jks -file client/client1.cer 

# Import public keys and certificates into each others keystores 

keytool -import -noprompt -trustcacerts -alias client1 -file client/client1.cer -keystore server/server.jks 
keytool -import -noprompt -trustcacerts -alias server -file server/server.cer -keystore client/client1.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore server/server.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore client/client1.jks 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\cacerts.jks" 
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\Java\jdk1.6\jre\lib\security\cacerts" 
move "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks.backup" 
copy server\server.jks "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" 

Nella console di amministrazione GlassFish, abilitare la sicurezza sul proprio listener http, spuntare le caselle SSL3, TLS e Client Authentication, impostare il certificato NickName sul server, il Key Store su config \ keystore.jks, il Trust Store per config \ keystore.jks, l'algoritmo di attendibilità su PKIX e lasciare la lunghezza massima del certificato a 5.

In NetBeans, creare un nuovo progetto di applicazione Web. All'interno di ciò, creare un nuovo servizio Web.

Il mio codice di Web Service si presentava così:

@WebService() 
public class ListProducts { 

    @Resource WebServiceContext context; 

    @WebMethod(operationName = "listProducts") 
    public String listProducts() { 
    return context.getUserPrincipal().toString(); 
    } 

} 

Fare clic destro sul Web Service e selezionare Modifica Web Service attributi. Spuntare la casella Servizio sicuro e selezionare Sicurezza certificati reciproci come meccanismo di sicurezza. Fare clic sul pulsante Configura ... e selezionare la casella Encrypt Signature. Ora deselezionare la casella Usa impostazioni predefinite di sviluppo e quindi fare clic sul pulsante Keystore. Impostare la posizione del keystore server.jks e selezionare l'alias server.Fai lo stesso per la configurazione del Truststore (anche se non devi selezionare un alias qui).

Importare il certificato client client1.p12 nel browser. Distribuisci il tuo servizio Web su Glassfish. Aprire il servizio Web in un browser e accedere al WSDL distribuito tramite HTTPS. Scarica il WSDL e altri schemi. Rinominare gli schemi di riferimento in copie locali in modo che quando si utilizza NetBeans WSDL2Java non vengano utilizzate risorse remote. (Questo paragrafo è perché hai limitato il tuo WSDL ai client con un certificato approvato ma NetBeans non può recuperarlo da remoto perché non ha accesso al certificato in questione).

Creare un nuovo progetto Java. Creare un nuovo client del servizio Web. Quando richiesto, indirizzare NetBeans al file WSDL salvato. Importare i file di libreria METRO2.0 (C:\Program Files\Netbeans 6.9\enterprise\modules\ext\metr\webservices-*.jar). Il mio codice si presentava così:

public static void main(String[] args) { 
    System.getProperties().put("javax.net.ssl.keyStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks"); 
    System.getProperties().put("javax.net.ssl.keyStorePassword", "changeit"); 
    System.getProperties().put("javax.net.ssl.trustStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks"); 
    System.getProperties().put("javax.net.ssl.trustStorePassword", "changeit"); 
    System.out.println(new ListProductsService().getListProductsPort().listProducts()); 
} 

Copy webservices-api.jar nel vostro Java \ jdk1.6 \ jre \ lib \ approvata. Fare clic con il tasto destro del mouse sul riferimento al servizio Web e selezionare Modifica attributi servizio Web. Impostare il percorso del keystore su client1.jks e impostare l'alias su client1. Impostare il percorso truststore su client1.jks e impostare l'alias su server.

Speriamo che si può ora eseguire il cliente e si dovrebbe vedere l'uscita in questo modo: [email protected], CN=Bob Smith, OU=Something, O=SomethingElse, L=AnyTown, ST=AnyState, C=US

Problemi correlati