2012-12-21 19 views
14

Sự khác nhau giữa việc sử dụng một đối tượng KeyStore cho kho khóa và kho tin cậy là gì; trái ngược với việc sử dụng KeyManager và TrustManager?Sự khác nhau giữa KeyStore và KeyManager/TrustManager

Hãy để tôi giải thích lý do tôi hỏi. Tôi đang làm việc với RESTEasy và cần thực hiện một cuộc gọi REST qua HTTPS với các chứng chỉ SSL. Tôi cần tăng thêm cách RESTEasy tạo ClientRequest. Dưới đây là những gì tôi đã tìm ra ban đầu:

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

Tôi chạy vào một vấn đề với các giấy chứng nhận Peer và tiếp tục nhận được một ngoại lệ:

javax.net.ssl.SSLPeerUnverifiedException: ngang hàng không được xác thực

Sau đó tôi tìm kiếm và tìm thấy các bài viết/blog về việc thiết lập HttpClient nhưng sử dụng TrustManager và KeyManager. Tôi đã tái cấu trúc mã để thực hiện các việc sau:

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

Mã thứ hai hoạt động tốt. Vì vậy, sự khác biệt giữa 2 loại tập quán là gì?

Trả lời

13

Tôi nghĩ rằng đây có thể giúp bạn: Difference between trustStore and keyStore in Java - SSL

Đầu tiên và khác biệt lớn giữa trustStore và keystore là trustStore được sử dụng bởi TrustManager và keystore được sử dụng bởi lớp KeyManager trong Java. KeyManager và TrustManager thực hiện các công việc khác nhau trong Java, TrustManager xác định liệu kết nối từ xa có đáng tin cậy hay không, tức là liệu bên từ xa có phải là người yêu cầu và KeyManager quyết định thông tin xác thực nào được gửi đến máy chủ từ xa để xác thực trong quá trình bắt tay SSL hay không. nếu bạn là một máy chủ SSL, bạn sẽ sử dụng khóa riêng trong thuật toán trao đổi khóa và gửi chứng chỉ tương ứng với khóa công khai của bạn tới máy khách, chứng chỉ này được lấy từ keyStore. Về phía máy khách SSL, nếu được viết bằng Java, nó sẽ sử dụng các chứng chỉ được lưu trữ trong trustStore để xác minh danh tính của Máy chủ.

Đọc thêm: http://javarevisited.blogspot.com/2012/09/difference-between-truststore-vs-keyStore-Java-SSL.html#ixzz2kelYSEDj

Các vấn đề liên quan