Hallo Leute,
ich bin gerade verzweifelt dabei zu versuchen eine HTTPS-Verbindung zu meinem Server herzustellen. Dabei soll eine Client-Authentifizierung zum Einsatz kommen. Ich habe mein Zertifikat in einer *.p12-Datei und habe damit auch erfolgreich geschafft, eine Verbindung herzustellen:
Nun möchte ich aber das Zertifikat über die Einstellungen in den KeyChain des Geräts laden, was auch geklappt. Nun bekomme ich es aber nicht mehr hin, den SSLContext so zu initialisieren, dass der Handshake erfolgreich ist.
Folgendes schlägt leider fehl:
Hier liegt vermutlich der Hund begraben, ich begreife aber einfach nicht, wie ich dem SSLContext beibringe, mein Zeritifkat aus dem KeyChain zu verwenden...
Ich hoffe mir kann jemand helfen...
ich bin gerade verzweifelt dabei zu versuchen eine HTTPS-Verbindung zu meinem Server herzustellen. Dabei soll eine Client-Authentifizierung zum Einsatz kommen. Ich habe mein Zertifikat in einer *.p12-Datei und habe damit auch erfolgreich geschafft, eine Verbindung herzustellen:
Java:
File p12File = new File("zertifikat.p12");
SSLContext sslctx = createContextFromPKCS12(p12File,"password".toCharArray());
...
static private SSLContext createContextFromPKCS12(File file, char[] passwd)
throws Exception
{
SSLContext sslctx = SSLContext.getInstance("TLS");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(file), passwd);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, passwd);
TrustManagerFactory tmf = createTrustManager(keyStore);
sslctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslctx;
}
...
// der trusted Keystore muss JKS-formatiert sein. Eine leerer Keystore
// wird mit den Zertifikaten aus dem privaten KeyStore gefüllt
static private TrustManagerFactory createTrustManager(KeyStore ksKeys)
throws Exception
{
KeyStore ksTrust = KeyStore.getInstance("BKS");
ksTrust.load(null,null);
for (Enumeration<String> enu = ksKeys.aliases(); enu.hasMoreElements();)
{
String s = (String) enu.nextElement();
Certificate[] acertificate = ksKeys.getCertificateChain(s);
if (acertificate == null)
continue;
for (int i = 0; i < acertificate.length; i++)
{
if ( (acertificate[i] instanceof X509Certificate))
{
X509Certificate cert = (X509Certificate)acertificate[i];
String name = cert.getSubjectDN().toString();
int from = name.indexOf("CN=") + 3;
int to = name.indexOf(",", from);
ksTrust.setCertificateEntry(name.substring(from, to), cert);
}
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(ksTrust);
return tmf;
}
Nun möchte ich aber das Zertifikat über die Einstellungen in den KeyChain des Geräts laden, was auch geklappt. Nun bekomme ich es aber nicht mehr hin, den SSLContext so zu initialisieren, dass der Handshake erfolgreich ist.
Folgendes schlägt leider fehl:
Java:
PrivateKey privateKey = KeyChain.getPrivateKey(E2dActivity.this, alias);
X509Certificate[] certificateChain = KeyChain.getCertificateChain(E2dActivity.this, alias);
Log.d(TAG, certificateChain.toString());
sslctx = SSLContext.getInstance("TLS");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// keyStore.load(new FileInputStream(file), passwd);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
// kmf.init(keyStore, passwd);
KeyStore ksTrust = KeyStore.getInstance("BKS");
ksTrust.load(null, null);
for (int i = 0; i < certificateChain.length; i++) {
if ((certificateChain[i] instanceof X509Certificate)) {
X509Certificate cert = (X509Certificate) certificateChain[i];
String name = cert.getSubjectDN().toString();
int from = name.indexOf("CN=") + 3;
int to = name.indexOf(",", from);
ksTrust.setCertificateEntry(name.substring(from, to), cert);
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(ksTrust);
sslctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
Hier liegt vermutlich der Hund begraben, ich begreife aber einfach nicht, wie ich dem SSLContext beibringe, mein Zeritifkat aus dem KeyChain zu verwenden...
Ich hoffe mir kann jemand helfen...