SSL-Client-Authentifizierung in Android 4.x
Ich würde gerne eine App erstellen, die die Verbindung zu einem server herstellt. Dieser server benutzt die SSL-Client-Authentifizierung. Die Nutzer der App sollte in der Lage sein zu wählen, das Zertifikat und ermöglichen die Verwendung von es wie es implementiert ist, in der browser-app.
In der browser-Anwendung die Authentifizierung funktioniert wie erwartet, also das Zertifikat ich verwenden gültig ist.
Wenn ich versuche zu verbinden in meiner App erhalte ich die folgende Fehlermeldung:
javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException:
SSL handshake terminated: ssl=0x2a2d3b38:
Failure in SSL library, usually a protocol error
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
(external/openssl/ssl/s3_pkt.c:1290 0x2a2df880:0x00000003)
Ich habe versucht, Folgen die android-Dokumentation für meine Anwendung.
Hier ist der code von meinem Probe-Aktivität:
public class ClientCertificateActivity extends Activity implements
KeyChainAliasCallback {
protected static final String TAG = "CERT_TEST";
private String alias;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
choseCertificate();
LinearLayout layout = new LinearLayout(this);
Button connectToServer = new Button(this);
connectToServer.setText("Try to connect to Server");
connectToServer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
connectToServer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
connectToServer();
}
});
layout.addView(connectToServer);
addContentView(layout, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
protected void connectToServer() {
final Context ctx = this;
new AsyncTask<Void, Void, Boolean>() {
private Exception error;
@Override
protected Boolean doInBackground(Void... arg) {
try {
PrivateKey pk = KeyChain.getPrivateKey(ctx, alias);
X509Certificate[] chain = KeyChain.getCertificateChain(ctx,
alias);
KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory
.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://usecert.example.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection) url
.openConnection();
urlConnection.setSSLSocketFactory(context
.getSocketFactory());
InputStream in = urlConnection.getInputStream();
return true;
} catch (Exception e) {
e.printStackTrace();
error = e;
return false;
}
}
@Override
protected void onPostExecute(Boolean valid) {
if (error != null) {
Toast.makeText(ctx, "Error: " + error.getMessage(),
Toast.LENGTH_LONG).show();
return;
}
Toast.makeText(ctx, "Success: ", Toast.LENGTH_SHORT).show();
}
}.execute();
}
protected void choseCertificate() {
KeyChain.choosePrivateKeyAlias(this, this,
new String[] { "RSA", "DSA" }, null, "m.ergon.ch", 443, null);
}
@Override
public void alias(String alias) {
this.alias = alias;
}
}
Ausnahme wird geworfen urlConnection.getInputStream();
Hier ist die Erfassung der handshake zwischen server und client.
Vielen Dank für alle Anregungen und tipps.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie nie initialisieren eines KeyManager mit Ihrem privaten Schlüssel, so dass es keine Möglichkeit gibt, die client-Authentifizierung kann es abholen.
Würden Sie implementieren müssen, um X509KeyManager, um Ihr PrivateKey und einige hart-codiert alias.
Hier ist der, den man aus der stock-E-Mail-Anwendung (ICS+) für die Referenz. Sie müssen möglicherweise ändern Sie es etwas, aber es sollte einfach zu Folgen ist: grundsätzlich ist es nur speichert der Schlüssel, alias und Zertifikat die Kette die Felder auf und gibt diese über die entsprechenden Methoden (
StubKeyManager
nur exceptions wirft für die nicht implementierten und nicht benötigte Methoden):X509KeyManager
um die Rückgabe IhrerPrivateKey
und einige hart-codiert alias. Sie sollten nicht implementieren müssen, um die server-bezogene Methoden. developer.android.com/reference/javax/net/ssl/...