2012-12-21 14 views
14

Qual è la differenza tra l'utilizzo di un oggetto KeyStore per il keystore e il truststore; al contrario di usare KeyManager e TrustManager?Differenza tra KeyStore e KeyManager/TrustManager

Lasciami spiegare perché lo sto chiedendo. Sto lavorando con RESTEasy e avevo bisogno di effettuare una chiamata REST su HTTPS con certificati SSL. Avevo bisogno di aumentare il modo in cui RESTEasy creava ClientRequest. Ecco quello che ho capito inizialmente:

public void afterPropertiesSet() throws Exception { 
    Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank."); 
    Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank."); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank"); 

    // Set the keystore and truststore for mutual authentication 
    createKeystore(); 
    createTruststore(); 

    if (getHttpClient() == null) { 
     // Initialize HTTP Client 
     initializeHttpClient(); 
    } 

    Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization"); 
} 

public ClientRequest createClientRequest(String uri) throws URISyntaxException { 
    ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient()); 
    ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri)); 
    return fac.createRequest(uri); 
} 

private void createTruststore() throws KeyStoreException, FileNotFoundException, IOException, 
     NoSuchAlgorithmException, CertificateException { 

    String truststoreFilePath = getTruststorePath() + getTruststoreName(); 

    KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    InputStream truststoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath); 
    truststore.load(truststoreInput, getTruststorePassword().toCharArray()); 
} 

private void createKeystore() throws KeyStoreException, FileNotFoundException, IOException, 
     NoSuchAlgorithmException, CertificateException { 

    String keystoreFilePath = getKeystorePath() + getKeystoreName(); 
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    InputStream keystoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath); 
    keystore.load(keystoreInput, getKeystorePassword().toCharArray()); 
} 

/** 
* Initializes the HTTP Client 
* 
* @throws KeyStoreException 
* @throws NoSuchAlgorithmException 
* @throws UnrecoverableKeyException 
* @throws KeyManagementException 
*/ 
private void initializeHttpClient() throws KeyManagementException, UnrecoverableKeyException, 
     NoSuchAlgorithmException, KeyStoreException { 

    // Register https and http with scheme registry 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    SSLSocketFactory sslSocketFactory = new SSLSocketFactory(getKeystore(), getKeystorePassword(), getTrustStore()); 
    schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory())); 
    schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory)); 

    // Set connection params 
    HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout); 
    HttpConnectionParams.setSoTimeout(httpParameters, readTimeout); 
    HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true); 

    // Create Connection Manager 
    PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry); 
    clientManager.setMaxTotal(maxTotalConnections); 
    clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost); 

    httpClient = new DefaultHttpClient(clientManager, httpParameters); 
} 

mi sono imbattuto in un problema con i certificati peer e continuato a ottenere un'eccezione:

javax.net.ssl.SSLPeerUnverifiedException: Peer non autenticato

Ho quindi cercato e trovato articoli/blog sulla configurazione di HttpClient ma usando TrustManager e KeyManager. Ho refactored il codice per effettuare quanto segue:

public void afterPropertiesSet() throws Exception { 
    Assert.isTrue(StringUtils.isNotBlank(getKeystoreName()), "Key Store Name is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getKeystorePassword()), "Key Store Password is Blank."); 
    Assert.isTrue(StringUtils.isNotBlank(getKeystorePath()), "Key Store Path is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststoreName()), "Trust Store Name is Blank"); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststorePassword()), "Trust Store Password is Blank."); 
    Assert.isTrue(StringUtils.isNotBlank(getTruststorePath()), "Trust Store Path is Blank"); 

    if (getHttpClient() == null) { 
     // Initialize HTTP Client 
     initializeHttpClient(); 
    } 

    Assert.notNull(getHttpClient(), "HTTP Client is NULL after initialization"); 
} 

public ClientRequest createClientRequest(String uri) throws URISyntaxException { 
    ClientExecutor clientExecutor = new ApacheHttpClient4Executor(getHttpClient()); 
    ClientRequestFactory fac = new ClientRequestFactory(clientExecutor, new URI(uri)); 
    return fac.createRequest(uri); 
} 

/** 
* Initializes the HTTP Client 
* 
* @throws KeyStoreException 
* @throws NoSuchAlgorithmException 
* @throws UnrecoverableKeyException 
* @throws KeyManagementException 
*/ 
private void initializeHttpClient() throws Exception { 

    if (isCheckPeerCertificates()) { 
     checkPeerCerts(); 
    } 

    // Create Trust and Key Managers 
    // Use TrustManager and KeyManager instead of KeyStore 
    TrustManager[] trustManagers = getTrustManagers(getTruststorePassword()); 
    KeyManager[] keyManagers = getKeyManagers(getKeystorePassword()); 

    // Create SSL Context 
    SSLContext ctx = SSLContext.getInstance("TLS"); 
    ctx.init(keyManagers, trustManagers, new SecureRandom()); 

    // Create SSL Factory 
    SSLSocketFactory sslSocketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

    // Register https and http with scheme registry 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme(HTTP, 80, PlainSocketFactory.getSocketFactory())); 
    schemeRegistry.register(new Scheme(HTTPS, 443, sslSocketFactory)); 

    // Set connection params 
    HttpConnectionParams.setConnectionTimeout(httpParameters, serviceConnectionTimeout); 
    HttpConnectionParams.setSoTimeout(httpParameters, readTimeout); 
    HttpConnectionParams.setStaleCheckingEnabled(httpParameters, true); 

    // Create Connection Manager 
    PoolingClientConnectionManager clientManager = new PoolingClientConnectionManager(schemeRegistry); 
    clientManager.setMaxTotal(maxTotalConnections); 
    clientManager.setDefaultMaxPerRoute(defaultMaxConnectionsPerHost); 

    httpClient = new DefaultHttpClient(clientManager, httpParameters); 
} 

private TrustManager[] getTrustManagers(String trustStorePassword) throws Exception { 
    String truststoreFilePath = getTruststorePath() + getTruststoreName(); 
    InputStream trustStoreInput = getClass().getClassLoader().getResourceAsStream(truststoreFilePath); 
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    trustStore.load(trustStoreInput, trustStorePassword.toCharArray()); 
    TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmfactory.init(trustStore); 
    return tmfactory.getTrustManagers(); 
} 

private KeyManager[] getKeyManagers(String keyStorePassword) throws Exception { 
    String keystoreFilePath = getKeystorePath() + getKeystoreName(); 
    InputStream keyStoreInput = getClass().getClassLoader().getResourceAsStream(keystoreFilePath); 
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    keyStore.load(keyStoreInput, keyStorePassword.toCharArray()); 
    KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmfactory.init(keyStore, keyStorePassword.toCharArray()); 
    return kmfactory.getKeyManagers(); 
} 

Il secondo codice funziona correttamente. Quindi, qual è la differenza tra i 2 tipi di utilizzo?

risposta

13

penso che questo può aiutare: Difference between trustStore and keyStore in Java - SSL

primo e principale differenza tra trustStore e keyStore è che trustStore viene utilizzato da TrustManager e keyStore viene utilizzato per classe KeyManager in Java. KeyManager e TrustManager eseguono un lavoro diverso in Java, TrustManager determina se la connessione remota debba essere considerata attendibile o meno, a prescindere dal fatto che sia la parte remota a chi asserire e KeyManager decida quali credenziali di autenticazione devono essere inviate all'host remoto per l'autenticazione durante l'handshake SSL. se si è un server SSL, si utilizzerà la chiave privata durante l'algoritmo di scambio delle chiavi e si inviano i certificati corrispondenti alle chiavi pubbliche al client, questo certificato viene acquisito da keyStore. Sul lato client SSL, se scritto in Java, utilizzerà i certificati memorizzati in trustStore per verificare l'identità del server.

Per saperne di più: http://javarevisited.blogspot.com/2012/09/difference-between-truststore-vs-keyStore-Java-SSL.html#ixzz2kelYSEDj