2012-09-06 19 views

Trả lời

0

Tôi giả sử bạn muốn làm https với chứng chỉ ứng dụng khách. Tôi nghĩ rằng điều này cần phải được thiết lập ở cấp độ jvm, có một lời giải thích tốt here làm thế nào để làm điều đó.

Có vẻ là một cách để làm điều này với ning trực tiếp, như đã giải thích here, mã được sao chép dưới đây,

// read in PEM file and parse with commons-ssl PKCS8Key 
// (ca.juliusdavies:not-yet-commons-ssl:0.3.11) 
RandomAccessFile in = null; 
byte[] b = new byte[(int) certFile.length()]; 
in = new RandomAccessFile(certFile, "r"); 
in.readFully(b); 
char[] password = hints.get("password").toString().toCharArray(); 
PKCS8Key key = new PKCS8Key(b, password); 

// create empty key store 
store = KeyStore.getInstance(KeyStore.getDefaultType()); 
store.load(null, password); 

// cert chain is not important if you override the default KeyManager and/or 
// TrustManager implementation, IIRC 
store.setKeyEntry(alias, key.getPrivateKey(), password, new DefaultCertificate[0]); 

// initialize key and trust managers -> default behavior 
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); 

// password for key and store have to be the same IIRC 
keyManagerFactory.init(store, password); 
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init(store); 
TrustManager[] trustManagers = tmf.getTrustManagers(); 

// override key and trust managers with desired behavior - for example 
// * 'trust everything the server gives us' -> TrustManager#checkServerTrusted 
// * 'always return a preset alias to use for auth' -> X509ExtendedKeyManager#chooseClientAlias, X509ExtendedKeyManager#chooseEngineClientAlias 
for (int i = 0; i < keyManagers.length; i++) 
{ 
    if (keyManagers[i] instanceof X509ExtendedKeyManager) 
    { 
    AHCKeyManager ahcKeyManager = new AHCKeyManager((X509ExtendedKeyManager) keyManagers[i]); 
    keyManagers[i] = ahcKeyManager; 
    } 
} 

for (int i = 0; i < trustManagers.length; i++) 
{ 
    if (tm instanceof X509TrustManager) 
    { 
    AHCTrustManager ahcTrustManager = new AHCTrustManager(manager, (X509TrustManager) trustManagers[i]); 
    trustManagers[i] = ahcTrustManager; 
    } 
} 

// construct SSLContext and feed to AHC config 
SSLContext context = SSLContext.getInstance("TLS"); 
context.init(keyManagers, trustManagers, null); 

ahcCfgBuilder.setSSLContext(context); 
+0

Thật khủng khiếp! Tôi hy vọng bạn là sai! : -/BTW, Công văn 0.9 dựa trên Ning Async HttpClient, dựa trên NIO. Vì vậy, câu trả lời phải làm việc cho điều đó - không nói liên kết bạn cung cấp không, chỉ cần đặt một số nhận xét ở đây cho bất kỳ ai khác đi lên. –

2

Dựa trên mã Java trong mẫu @sbridges, tôi đã đưa ra sau mã Scala sử dụng công văn. Nó tạo ra một bối cảnh SSL tùy chỉnh có chứa các chứng chỉ mà bạn cung cấp (và chỉ những người đó; kho lưu trữ gốc mặc định của chứng chỉ gốc đáng tin cậy không được sử dụng bởi mã này khi xác minh máy chủ từ xa).



    class SslAuthenticatingHttp(certData: SslCertificateData) extends Http { 
     override val client = new AsyncHttpClient(
     (new AsyncHttpClientConfig.Builder).setSSLContext(buildSslContext(certData)).build 
    ) 

     private def buildSslContext(certData: SslCertificateData): SSLContext = { 
     import certData._ 

     val clientCertStore = loadKeyStore(clientCertificateData, clientCertificatePassword) 
     val rootCertStore = loadKeyStore(rootCertificateData, rootCertificatePassword) 

     val keyManagerFactory = KeyManagerFactory.getInstance("SunX509") 
     keyManagerFactory.init(clientCertStore, clientCertificatePassword.toCharArray) 
     val keyManagers = keyManagerFactory.getKeyManagers() 

     val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) 
     trustManagerFactory.init(rootCertStore) 
     val trustManagers = trustManagerFactory.getTrustManagers() 

     val context = SSLContext.getInstance("TLS") 
     context.init(keyManagers, trustManagers, null) 

     context 
     } 

     private def loadKeyStore(keyStoreData: Array[Byte], password: String): KeyStore = { 
     val store = KeyStore.getInstance(KeyStore.getDefaultType) 
     store.load(new ByteArrayInputStream(keyStoreData), password.toCharArray) 
     store 
     } 
    } 

    case class SslCertificateData (
     clientCertificateData: Array[Byte], 
     clientCertificatePassword: String, 
     rootCertificateData: Array[Byte], 
     rootCertificatePassword: String) 

mà sẽ được sử dụng như trong:

Lưu ý rằng điều này giữ cho dữ liệu chứng chỉ trong bộ nhớ, đó không phải là cách an toàn nhất để làm điều đó và tiêu thụ bộ nhớ không cần thiết. Nó có thể trong nhiều trường hợp phù hợp hơn để lưu trữ một InputStream hoặc một tên tệp trong lớp trường hợp SslCertificateData.

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