Devo essere in grado di inviare un file di certificato (.pem, credo), con una richiesta di ottenere usando scala e dispatch.Invia file di certificato con Scala Dispatch
Come si fa?
Devo essere in grado di inviare un file di certificato (.pem, credo), con una richiesta di ottenere usando scala e dispatch.Invia file di certificato con Scala Dispatch
Come si fa?
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);
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.
È 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. –