Разница между KeyStore и KeyManager/TrustManager - программирование
Подтвердить что ты не робот

Разница между KeyStore и KeyManager/TrustManager

В чем разница между использованием объекта KeyStore для хранилища ключей и доверия? в отличие от использования KeyManager и TrustManager?

Позвольте мне объяснить, почему я спрашиваю. Я работаю с RESTEasy и должен сделать REST-вызов через HTTPS с сертификатами SSL. Мне нужно было увеличить, как RESTEasy создал ClientRequest. Вот что я понял изначально:

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);
}

Я столкнулся с проблемой с сертификатами Peer и продолжал получать исключение:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

Затем я искал и нашел статьи/блоги о настройке HttpClient, но используя TrustManager и KeyManager. Я реорганизовал код, чтобы сделать следующее:

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();
}

Второй код работает просто отлично. Итак, какова разница между двумя типами использования?

4b9b3361

Ответ 1

Я думаю, это может вам помочь: Разница между trustStore и keyStore в Java - SSL

Первое и основное различие между trustStore и keyStore заключается в том, что trustStore используется TrustManager, а keyStore используется классом KeyManager в Java. KeyManager и TrustManager выполняет различную работу в Java, TrustManager определяет, нужно ли доверять удаленное соединение или нет, то есть, является ли удаленная сторона тем, к кому она относится, и KeyManager решает, какие учетные данные аутентификации должны быть отправлены на удаленный хост для аутентификации во время установления связи SSL. если вы являетесь сервером SSL, вы будете использовать закрытый ключ во время алгоритма обмена ключами и отправлять сертификаты, соответствующие вашим открытым ключам клиенту, этот сертификат будет получен из keyStore. На стороне клиента SSL, если он написан на Java, он будет использовать сертификаты, хранящиеся в trustStore, для проверки подлинности сервера.

Подробнее: http://javarevisited.blogspot.com/2012/09/difference-between-truststore-vs-keyStore-Java-SSL.html#ixzz2kelYSEDj