|
| 1 | +Android Pinning |
| 2 | +================= |
| 3 | + |
| 4 | +libpinning is a standalone Android library project that facilitates certificate pinning for SSL |
| 5 | +connections from Android apps, in order to minimize dependence on Certificate Authorities. |
| 6 | + |
| 7 | +CA signatures are necessary for *general purpose* network communication tools: things like web |
| 8 | +browsers, which connect to arbitrary network endpoints and have no advance knowledge of what the SSL |
| 9 | +certificates for those endpoint should look like. |
| 10 | + |
| 11 | +Most mobile apps are not *general purpose* communication tools. Instead, they typically connect |
| 12 | +directly to a narrow set of backend services that the app's author either controls, or can |
| 13 | +predict ahead of time. |
| 14 | + |
| 15 | +This creates an opportunity for app developers to sidestep the security problems inherent with |
| 16 | +Certificate Authorities. The best way is to throw CA certificates out the window entirely by |
| 17 | +signing your own endpoint certificates with your own offline signing certificate, which you then |
| 18 | +distribute with your app. See [this blog post](http://thoughtcrime.org/blog/authenticity-is-broken-in-ssl-but-your-app-ha/) |
| 19 | +for examples of the no-CA technique. |
| 20 | + |
| 21 | +Sometimes, however, that's not possible, and you need to continue using CA certificates for one |
| 22 | +reason or another. Perhaps the API endpoint is shared with a web browser's endpoint, for instance. |
| 23 | + |
| 24 | +In that case, it's necessary to employ "pinning," which is simply the act of verifying that the |
| 25 | +certificate chain looks the way you know it should, even if it's signed by a CA. This prevents |
| 26 | +*other* CAs from being able to effectively create forged certificates for your domain, as with the |
| 27 | +many Comodo breaches, the DigiNotar breach, and the TurkTrust breach. |
| 28 | + |
| 29 | +This library is designed to make pinning easier on Android. It's structured as an Android library |
| 30 | +project, so you can simply link it to your own project and begin. |
| 31 | + |
| 32 | +Examples |
| 33 | +----------- |
| 34 | + |
| 35 | +Using a simple `HttpsURLConnection` with a `PinningTrustManager`: |
| 36 | + |
| 37 | +``// Define an array of pins. One of these must be present |
| 38 | +// in the certificate chain you receive. A pin is a hex-encoded |
| 39 | +// hash of a X.509 certificate's SubjectPublicKeyInfo. A pin can |
| 40 | +// be generated using the provided pin.py script: |
| 41 | +// python ./tools/pin.py certificate_file.pem |
| 42 | +String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}; |
| 43 | +URL url = new URL("https://www.google.com"); |
| 44 | +HttpsURLConnection connection = PinningHelper.getPinnedHttpsURLConnection(context, pins, url); |
| 45 | + |
| 46 | +return connection.getInputStream(); |
| 47 | +`` |
| 48 | + |
| 49 | +Using a simple ``HttpClient` with a `PinningTrustManager`: |
| 50 | + |
| 51 | +``String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}; |
| 52 | +HttpClient httpClient = PinningHelper.getPinnedHttpClient(context, pins); |
| 53 | + |
| 54 | +HttpResponse response = httpClient.execute(new HttpGet("https://www.google.com/")); |
| 55 | +`` |
| 56 | + |
| 57 | +It's also possible to work with `PinningTrustManager` and `PinningSSLSocketFactory` more directly: |
| 58 | + |
| 59 | +``String[] pins = new String[] {"40c5401d6f8cbaf08b00edefb1ee87d005b3b9cd"}; |
| 60 | +SchemeRegistry schemeRegistry = new SchemeRegistry(); |
| 61 | +schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); |
| 62 | +schemeRegistry.register(new Scheme("https", new PinningSSLSocketFactory(getContext() ,pins, 0), 443)); |
| 63 | + |
| 64 | +HttpParams httpParams = new BasicHttpParams(); |
| 65 | +ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry); |
| 66 | +DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager, httpParams); |
| 67 | + |
| 68 | +HttpResponse response = httpClient.execute(new HttpGet("https://www.google.com/")); |
| 69 | +`` |
| 70 | + |
| 71 | +Issues |
| 72 | +----------- |
| 73 | + |
| 74 | +Have a bug? Please create an issue here on GitHub! |
| 75 | + |
| 76 | +https://github.com/moxie0/AndroidPinning/issues |
| 77 | + |
| 78 | +License |
| 79 | +--------------------- |
| 80 | + |
| 81 | +Copyright 2011-2013 Moxie Marlinspike |
| 82 | + |
| 83 | +Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html |
| 84 | + |
| 85 | +Please contact me if this license doesn't work for you. |
0 commit comments