2012-09-06 18 views

risposta

0

Suppongo che si desideri eseguire https con i certificati client. Penso che questo debba essere impostato a livello jvm, c'è una buona spiegazione here come farlo.

Sembra che ci sia un modo per fare questo con ning direttamente, come spiegato here, il codice viene copiato sotto,

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

È così terribile! Spero tu abbia torto! : -/BTW, Dispatch 0.9 è basato su Nuting Async HttpClient, che è basato su NIO. Quindi la risposta deve funzionare per quello - non dire che il link che hai fornito non lo fa, solo mettendo qualche osservazione qui per chiunque altro venga fuori. –

2

Sulla base del codice Java in mostra @sbridges, mi si avvicinò con la seguendo il codice Scala utilizzando la spedizione. Crea un contesto SSL personalizzato contenente i certificati forniti (e solo quelli; l'archivio predefinito di certificati radice attendibili non viene utilizzato da questo codice durante la verifica dell'host remoto).



    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) 

che sarebbe utilizzato come in:

Si noti che questo mantiene i dati del certificato in memoria, che non è il modo più sicuro per farlo e consuma la memoria inutilmente. In molti casi può essere più adatto per memorizzare un InputStream o un nome file nella classe del case SslCertificateData.