Archive for » 2010 «
Two weeks ago I got the task to establish TLS secured connections via certificates to a service endpoint.
I thought it’s not a big deal, because the endpoint already uses an EV certificate from a trusted CA (SwissSign) in Switzerland. Therefore I shouldn’t have to worry that the certificate would be considered as untrusted so I don’t have to import it to the trusted certs in the Java key store etc.
FAIL! I’ve got a security exception, cert is not trusted. Same problem when I visit the website with the browser. Ok, that’s bad, SwissSign is not such a big player like thawte, so, it needs some time till it will be added to the android trusted CA list. But, when I visit thawte.com, their cert is also not trusted by android. WTF?
Windows Phone and iPhone trust my SwissSign CA and don’t complain.
So, let’s ask google, stackoverflow and the blogosphere. Found a lot of solutions how to disable certificate checking entirely.
Yeah, great, this will solve my problem, my connection will be “secure” and everyone will be able to intercept my connection and inject his own certificate. But I finally found the solution with help from other sites and some testing and debugging.
The Solution
The following main steps are required to achieve a secured connection from trusted Certification Authorities.
- Grab all required certificates (root and any intermediate CA’s)
- Create a keystore with keytool and the BouncyCastle provider and import the certs
- Load the keystore in your android app and use it for the secured connections
- Don’t use the standard java.net.ssl.HttpsURLConnection for the secure connection. Use the Apache HttpClient (Version 4 atm) library, which is already built-in in android. It’s built on top of the java connection libraries and is, in my opinion, faster, better modularized and easier to understand.
Step 1: Grab the certs
You have to obtain all certificates that build a chain from the endpoint certificate the whole way up to the Root CA. This means, any (if present) Intermediate CA certs and also the Root CA cert. You don’t need to obtain the endpoint certificate.
You can obtain those certs from the chain (if provided) included in the endpoint certificate or from the official site of the issuer (in my case SwissSign).
Ensure that you save the obtained certificates in the Base64 encoded X.509 format. The content should look similar to this:
-----BEGIN CERTIFICATE----- MIIGqTC..... -----END CERTIFICATE-----
Step 2: Create the keystore
Download the BouncyCastle Provider and store it to a known location.
Also ensure that you can invoke the keytool command (usually located under the bin folder of your JRE installation).
Now import the obtained certs (don’t import the endpoint cert) into a BouncyCastle formatted keystore.
I didn’t tested it, but I think the order of importing the certificates is important. This means, import the lowermost Intermediate CA certificate first and then all the way up to the Root CA certificate.
With the following command a new keystore (if not already present) with the password mysecret will be created and the Intermediate CA certificate will be imported. I also defined the BouncyCastle provider, where it can be found on my file system and the keystore format. Execute this command for each certificate in the chain.
keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Verify if the certificates were imported correctly into the keystore:
keytool -list -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Should output the whole chain:
RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93 IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43
Now you can copy the keystore as a raw resource in your android app under res/raw/
Step 3: Use the keystore in your app
First of all we have to create a custom Apache HttpClient that uses our keystore for HTTPS connections:
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "mysecret".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
We have created our custom HttpClient, now we can just use it for secure connections. For example when we make a GET call to a REST resource.
// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();
That’s it. Took me long to figure it out, hope this helps and saves you that time.
I really hope that the android platform will implement a better mechanism in future releases for defining which Certification Authorities should be trusted or not or just expand their own trusted CA list. If they don’t, I can’t believe they will get good acceptance from the business sector. Ok, you can control which certificates you want to trust in your app, but you still can’t add thawte as a trusted CA in the android keystore and your browser will always complain about an untrusted CA. The only way I know to eliminate this problem is to root your phone (very user friendly) and add your CA manually to the android keystore.
Feel free to comment.
Stefan und ich haben vom 4. bis 5. Juni eine zweitägige Velotour um den Lac Léman durchgeführt.
Mache diesen Post nur um zu sehen, ob die geocodierten Bilder auch korrekt mit dem WordPress XML Google Maps Plugin auf der Karte angezeigt werden.
Leider habe ich noch nicht herausgefunden, wie man in die gleiche Karte den aufgezeichneten GPS Pfad als weiteres Layer einbinden kann. Wäre evtl. eine mögliche Erweiterung für das Plugin.
Nee, ich war nicht wirklich in Amsterdam. Es war zwar geplant, aber da die Franzosen an der WM rausgeflogen sind haben die Mitarbeiter am Basel/Mulhouse Flughafen gestreikt. Ergo, der Flug wurde gestrichen
Da musste ich halt spontan nach Alternativen suchen und entschied mich bei dem schönen Wetter für eine kleine Velotour nach Lungern.
Habe die Tour mit GPS festgehalten und dachte mir, ich könnte doch die ganze Strecke mit Google Maps in meinem WordPress Blog einbinden.
Habe das XML Google Maps Plugin von Patrick Matusz verwendet. Und siehe da, das Plugin funktioniert auch auf die neuste WordPress Version 3. Vielen Dank Patrick für deine wertvolle Arbeit.
Das Plugin kann sogar noch viel mehr:
- Anzeige von Streckeninformationen (Höhe, Geschwindigkeit etc.) und sogar, falls vorhanden, die aufgezeichnete Pulsfrequenz.
- Direkte Einbindung von Picasa Webalben (Bilder werden direkt auf der Karte angezeigt) und My Google Maps
- Support für das neue Google Earth Browser Plugin
- Integration von geoRSS Feeds und externen, dynamischen XML-Dateien (z.B. Flickr geoRSS oder Flickr KML)
- Integration von geocodierten NextGEN Gallery Bildern (direkte Anzeige auf der Karte)
Zu jedem Feature gibts auch jeweils ein entsprechendes Beispiel.
So, fertig gelabert, nun die eigentliche Velostrecke:
Zehn Minuten nach der Erstellung war der Kiddie-Eintrag bereits wieder von den Wikipedia Moderatoren gelöscht worden.
Erstaunlich mit welchem Blödsinn Kiddies ihre wertvolle Freizeit verschwenden können.
Konnte knapp noch einen Screenshot vom Artikel machen. Originaltext zur Mandschu-Zeit
Die SuisseID ist seit über einem Monat lanciert. Erst ein mal ein grosses Lob an das gesamte Team und deren Partner. Sie haben es geschafft in sehr kurzer Zeit die Spezifikation zu entwerfen und diese zu einem grossen Teil zu implementieren.
Für diejenigen, die nicht wissen was die SuisseID ist, hier ein Ausschnitt aus Wikipedia:
Die SuisseID ist der erste standardisierte elektronische Identitätsnachweis der Schweiz, mit dem sowohl eine rechtsgültige elektronische Signatur wie auch eine sichere Authentifizierung (Log-in) möglich sind. Mit der als USB-Stick oder Chipkarte erhältlichen SuisseID können Geschäfte von Privatpersonen mit Firmen bzw. Verwaltungen direkt und sicher über das Internet oder per E-Mail abgeschlossen werden.
Jeder, der sich noch weiter für die SuisseID interessiert, kann auch einen Blick in ihre Spezifikation werfen.
Habe kürzlich einen Artikel in der Weltwoche entdeckt Teure Lösung für nichtexistente Probleme, welcher sich kritisch über die SuisseID äussert.
Als ich den Artikel gelesen habe, hat es mir fast die Sprache verschlagen. Eine solche Schwarzmalerei und unsachgemässe Recherche kann man ja vom Blick erwarten
aber die Weltwoche scheint da wohl nicht besser zu sein. Der Autor schreibt frei aus der Seele und lästert über die SuisseID, hat wohl aber selber nie die Spezifikation der SuisseID gelesen und deren eigentlichen Zweck begriffen. Er stempelt sie als proprietäres, eigenbrötlerisches Schweizer Produkt ab, welches “eine digitale Mauer um unser Land” darstellt. Dabei basiert die SuisseID auf offenen Standards und lässt die Integration in bestehende Infrastruktur grundsätzlich zu.
Der Autor hätte sich mit einem Fachmann zusammensetzen sollen, bevor er den Artikel schrieb. Dies hilft, dass die Schere zwischen Endanwender und “IT Freak” nicht zu weit auseinanderklafft und beide Parteien einen Dialog führen, damit eine (gute) Lösung nicht wieder einmal in Vergessenheit gerät ohne jemals ihren wahren Nutzen erfahren zu haben. Anstatt nur auf die SuisseID in der Presse einzuprügeln und die Leute somit zu bekehren, sollte man als Autor versuchen das SuisseID Projekt und die technischen Möglichkeiten und Einschränkungen zu verstehen und somit sachgemäss über das Produkt zu berichten. Ja, es sind 21 Millionen CHF auf dem Spiel. Und mit solchen Artikeln muss man sich nicht wundern, wenn am Schluss niemand davon Gebrauch macht und das Geld verpufft.
Ich möchte nun selber Stellung nehmen zu einigen Punkten, welche im Artikel erwähnt werden:
Nun, ich kaufe heute schon meine Konzerttickets online, auch die Fahrscheine für Zugfahrten bei der SBB, ich nutze Telebanking, bestelle online bei diversen Shops Waren, usw. Wo genau liegt das Problem? Bei all diesen Angeboten habe ich mich einmal registriert und nutze sie fortan problemlos.
Ja das ist ja schön und recht. Soll von mir aus auch weiterhin so bleiben. Zwar ärgerlich, dass man für jede Seite oder jedes Angebot einen zusätzlichen Benutzernamen und Passwort braucht. Verleitet doch den Benutzer dazu sehr einfache Passwörter zu gebrauchen und dazu meistens immer das gleiche. Dank Phishing & Co. kann man schlimmstensfalls nach Herausinfden des Passworts auf all diejenigen Angebote zugreifen.
Da sehe ich den Vorteil einer SuisseID oder eines SAML Tokens. Kryptologisch betrachtet ist es sehr viel sicherer (SmartCard mit persönlicher PIN, Biometrie wäre noch besser) zudem braucht man sich nur noch einen PIN Code zu merken. Nämlich den PIN Code der SuisseID bzw. des SAML Tokens oder der Informaton Card (SuisseID unterstützt diese Formate).
Wir sind eine Exportnation, unsere Geschäftspartner im Ausland werden mit der SuisseID wohl kaum viel anfangen können. Kommt dazu, dass zwischen Unternehmen meistens eine langfristige Beziehung besteht und es somit auch da kaum Probleme mit nicht vorhandenen digitalen Unterschriften gibt.
Die Frage hier ist nicht ob die Geschäftspartner was mit der SuisseID anfangen. Die Frage ist, ob sie was mit digitalen Unterschriften anfangen können. Ob hinter der digitalen Unterschrift eine SuisseID dahintersteckt, oder eine BELPIC (Belgien) oder eine BULSTAT (Bulgarien) uvm, spielt keine grosse Rolle. Das wichtigste ist hierbei, dass das darunterliegende Zertifikat und Krypto-Verfahren standardisiert ist. Und dies ist bei der SuisseID ebenfalls der Fall. Welche EU Länder bereits schon eGov-Vorstösse wie die SuisseID betreiben oder solche Lösungen bereits schon realisiert haben findet man in der eID Interoperability for Pan-European eGovernment Services.
Das letzte Beispiel, welches jeweils angeführt wird, ist die Alterskontrolle für Einkäufe von Produkten, die für Jugendliche nicht geeignet sind. Spiele und Videos ab 18 Jahren, alkoholische Getränke usw. Neben der Tatsache, dass auch mit der SuisseID solche Hürden durch jugendliche Kreativität ohne Probleme umgangen werden können, sei noch erwähnt, dass die Alterskontrolle auch über die Kreditkarte durchgeführt werden könnte.
Das ein Jugendlicher die Kreditkarte seines Vaters mal schnell “entwendet”, das ist jugendliche Kreativität. Das ein Jugendlicher ein Krypto-Verfahren mal so schnell knackt, WOW, dann wäre das ein Top10-Hacker, dessen sechs- bis siebenstelligen Lohn ich gerne hätte. Zudem bräuchte er nebst enorm (!) viel Rechenpower auch mathematische Kenntnisse. Leider verheissen die jüngsten PISA Studien nichts gutes über die Coolnes von Mathe bei Jugendlichen.
Natürlich, das Bewusstsein über die Tragweite einer Weitergabe des PIN Codes einer SuisseID an andere Personen ist in der Bevölkerung bei weitem nicht verankert. Dies ist tatsächlich ein Problem. Aber nicht nur bei der SuisseID sondern generell bei Passwörtern. Z.B. ein vermeintlicher Bluewin Mitarbeiter ruft an und meldet einen geplanten Unterbruch des Internetzugangs an. Er bräuchte schnell das Passwort, damit er die Leitung anschliessend wieder reaktivieren kann.
Wenn man aber die SuisseID künftig z.B. auch für die digitale Steuererklärung, elektronische Abstimmung, dem eBanking und als elektronische Identitätskarte nutzt, da überlegt man sich zwei Mal ob man so schnell den PIN Code jemandem anderen anvertraut. Ich meine, kenne niemanden der seinen PIN Code seiner Bankkarte jemandem anderen anvertraut (ohne ihn wenigstens anschliessend zu ändern).
Gleichzeitig aber würden wir uns – sollte sich denn das behördlich verordnete System durchsetzen - vielen gesellschaftlich äusserst fragwürdigen neuen Möglichkeiten staatlicher Kontrolle aussetzen. Es würde wohl nicht lange dauern, bis die Online-Altersverifikation mittels SuisseID für -zig Produkte obligatorisch erklärt würde.
Im schlimmsten Fall könnte die SuisseID grundsätzlich zur Voraussetzung werden, um überhaupt online gehen zu können.
Da stimme ich voll und ganz zu! Es muss mit Vorsicht genossen werden. Es darf nicht sein, dass der Staat dies als Möglichkeit betrachtet völlige staatliche Kontrolle zu erreichen. Die SuisseID soll nur für ganz gezielte Anwendungen (Abstimmung etc.) Pflicht sein. Die Online-Shops sollten selber bestimmen dürfen, ob sie die SuisseID (oder generell SAML) als zusätzliches Authentisierungsverfahren nutzen möchten.
Mit der SuisseID bauen wir eine digitale Mauer um unser Land, denn für unseren kleinen Markt werden ausländischen Anbieter kaum eine weitere Extrawurst implementieren.
Ich zitiere hier gerne einen User-Kommentar zu einem weiteren SuisseID kritischen Blogeintrag des Autors:
Und das ganze via SAML 2.0. Da ist nichts SuisseID spezifisches dabei was die Schweizer selbst erfunden haben. Das sind offene Standards keine Ricolas.
Nun meine Bitte für das nächste Mal an Herr Gunten: Informieren Sie sich zuerst genau bevor Sie solche Artikel schreiben. Ich stehe, soweit mein Wissen es ermöglicht, auch gerne bei Fragen zur Verfügung.
Das ich sowas mal erleben darf.
Webseiten, welche nicht bei allen Browsern korrekt angezeigt werden gibt es viele. Aber das mal der Internet Explorer diskriminiert wird hätte ich nie gedacht. Ist ja doch alles IE optimiert, damit der grosse Nutzeranteil die Seite korrekt sieht.
Aber Ausnahmen bestätigen bekanntlich die Regel.
Ich bin kürzlich über den Blog von Scott Hanselman gestossen und war beeindruckt.
Viele State of the Art Einträge über Microsoft Produkte (auch CTPs), Codebeispiele, Guidelines und Tools, die kein Entwickler missen will.
Um stets auf dem aktuellen Stand zu bleiben bietet sich neben dem RSS Feed auch ein Weekly Podcast an.
Ein kürzlich von ihm gehaltene Präsentation Web Deployment Made Awesome: If You’re Using XCopy, You’re Doing It Wrong zeigt sehr ausdrücklich die neuen Deployment-Möglichkeiten (vorallem für ASP.NET) von Visual Studio 2010. Deployment ist an sich keine interessante Arbeit und ich bin sehr froh, dass künftig dem Entwickler dabei viel mühselige Arbeit abgenommen wird.
Besonderes Highlight: Eine ASP.NET Webaaplikation kann im Package auch die IIS Einstellungen enthalten, welche beim Deployment automatisch in den IIS geladen werden. Es können auch eigene Parameter für die Einstellungen definiert werden (siehe Präsentation @30:50). Während der Installation erstellt MSDeploy automatisch ein grafisches Eingabeformular, worin der Benutzer die Parameter bequem eingeben kann (z.B. Datenbankpassword, Webservice URL, ACL’s, …) und diese beim Einspielen in den IIS übernommen werden.




