The blog post can be found here.
In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.
The blog post can be found here.
In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.
<?xml version="1.0" encoding="utf-8"?> | |
<network-security-config> | |
<!-- Official Android N API --> | |
<!--https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html--> | |
<domain-config> | |
<domain>currency-converter-demo.pdm.approov.io</domain> | |
<trust-anchors> | |
<!--<certificates src="user" />--> | |
<certificates src="system" /> | |
</trust-anchors> | |
<pin-set> | |
<!-- Pin for: currency-converter-demo.pdm.approov.io --> | |
<pin digest="SHA-256">qXHiE7hFX2Kj4ZCtnr8u8yffl8w9CTv6kE0U5j0o1XY=</pin> | |
<!-- Backup Pin for: currency-converter-demo.pdm.approov.io --> | |
<pin digest="SHA-256">47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=</pin> | |
</pin-set> | |
<!-- TrustKit Android API --> | |
<!-- enforce pinning validation --> | |
<trustkit-config enforcePinning="true" disableDefaultReportUri="true"> | |
<!-- Add a reporting URL for pin validation reports --> | |
<report-uri>https://report.pdm.approov.io/pinning-violation/report</report-uri> | |
</trustkit-config> | |
</domain-config> | |
</network-security-config> |
<application | |
... | |
android:networkSecurityConfig="@xml/network_security_config" | |
... | |
> |
public RequestQueue getRequestQueue() { | |
if (requestQueue == null) { | |
// getApplicationContext() is key, it keeps you from leaking the | |
// Activity or BroadcastReceiver if someone passes one in. | |
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext()); | |
} | |
return requestQueue; | |
} |
public RequestQueue getRequestQueue() { | |
if (requestQueue == null) { | |
Context context = ctx.getApplicationContext(); | |
// TRUSTKIT | |
TrustKit.initializeWithNetworkSecurityConfiguration(context); | |
String serverHostname = null; | |
try { | |
URL url = new URL(baseUrl); | |
serverHostname = url.getHost(); | |
Log.i(LOG_TAG, "Server Hostname: " + serverHostname); | |
} catch (MalformedURLException e) { | |
Log.e(LOG_TAG, e.getMessage()); | |
} | |
// TRUSTKIT | |
requestQueue = Volley.newRequestQueue(context, new HurlStack(null, TrustKit.getInstance().getSSLSocketFactory(serverHostname))); | |
} | |
return requestQueue; | |
} |
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext()); |
requestQueue = Volley.newRequestQueue(context, new HurlStack(null, TrustKit.getInstance().getSSLSocketFactory(serverHostname))); |
$ ./stack setup | |
'.env.example' -> '.env' | |
'./mobile-app/android/app/src/main/cpp/api_key.h.example' -> './mobile-app/android/app/src/main/cpp/api_key.h' |
#ifndef API_KEY_H | |
#define API_KEY_H "the-api-key-will-be-here" | |
#endif |