2012-09-06 5 views

Antwort

0

Ich nehme an, Sie möchten https mit Client-Zertifikaten tun. Ich denke, das muss auf der Ebene von jvm eingerichtet werden, es gibt eine gute Erklärung here, wie es geht.

Es scheint ein Weg, dies direkt mit ning zu tun, wie here erklärt, der Code unten kopiert wird,

// 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

Das ist so schrecklich! Ich hoffe du irrst dich! : -/BTW, Dispatch 0.9 basiert auf Ning Async HttpClient, der auf NIO basiert. Also muss die Antwort dafür funktionieren - nicht zu sagen, dass der Link, den du zur Verfügung gestellt hast, nicht so ist, sondern nur eine Bemerkung für irgendjemanden, der auftaucht. –

2

Basierend auf dem Java-Code in @sbridges Probe, mich mit der aufkommen folgenden Scala-Code mit Versand. Es erstellt einen benutzerdefinierten SSL-Kontext, der die von Ihnen bereitgestellten Zertifikate enthält (und nur diese; der Standardspeicher vertrauenswürdiger Stammzertifikate wird von diesem Code bei der Überprüfung des Remote-Hosts nicht verwendet).



    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) 

, die wie in verwendet werden würde:

Beachten Sie, dass dies die Zertifikatsdaten im Speicher hält, was nicht der sicherste Weg ist, es zu tun und verbraucht unnötig Speicher. Es kann in vielen Fällen besser geeignet sein, einen InputStream oder einen Dateinamen in der SslCertificateData-Fallklasse zu speichern.

Verwandte Themen