Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

What a developer must care about Secure Android Applications Tamas Balogh Tech lead @ AutSoft

Slide 3

Slide 3 text

github.com/BaloghTamas/DevFest17AppSecurity

Slide 4

Slide 4 text

Network Security

Slide 5

Slide 5 text

HTTP + Transport Layer Security TLS: Transport layer HTTP: Application layer What about GET params? • Encrypted, but logged on the server! HTTPS Network Security http://nhprice.com/what-is-ios-model- the-overall-explanation-of-ios-7- layers.html

Slide 6

Slide 6 text

Latest version: TLS 1.2 On Android - Fragmented Supported vs Enabled Transport Layer security Network Security https://developer.android.com/reference/javax/net/ssl/SSLSocket.html

Slide 7

Slide 7 text

class ForceTlsSocketFactory @Throws(KeyManagementException::class, NoSuchAlgorithmException::class) constructor(val internalSSLSocketFactory: SSLSocketFactory) : SSLSocketFactory() { @Throws(IOException::class) override fun createSocket(): Socket { return enableTLSOnSocket(internalSSLSocketFactory.createSocket()) } //... private fun enableTLSOnSocket(socket: Socket?): Socket { if (socket != null && socket is SSLSocket) { socket.enabledProtocols = arrayOf("TLSv1.1", "TLSv1.2") } return socket!! } } Force TLS 1.2 Network Security

Slide 8

Slide 8 text

val builder = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) // For below API 16 use TLS 1.0 if (FORCE_TLS_1_2) { if (Build.VERSION.SDK_INT >= 16) { builder.tlsVersions(TlsVersion.TLS_1_2) } } if (Build.VERSION.SDK_INT >= 20) { builder.tlsVersions(TlsVersion.TLS_1_2) } val client = OkHttpClient.Builder() .connectionSpecs(listOf(builder.build())) .build() Usage with OkHttp 3 Network Security

Slide 9

Slide 9 text

Dashboards Network Security https://developer.android.com/about/dashboards/index.html

Slide 10

Slide 10 text

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS - Defines TLS/SSL ECDHE – Key agreement protocol RSA – Authentication protocol AES_256_GCM – Block cipher/Key size/Block mode SHA384 – Message authentication function Cipher Suits Network Security

Slide 11

Slide 11 text

Cipher Suits Network Security https://developer.android.com/reference/javax/net/ssl/SSLSocket.html

Slide 12

Slide 12 text

//Not secure enough, but compatible - OkHttp Docs: The following ciphers are on the HTTP/2's bad cipher suites list if (Build.VERSION.SDK_INT >= API_LEVEL_11) { builder.cipherSuites( CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) } //Secure - Chrome 51 supports if (Build.VERSION.SDK_INT >= API_LEVEL_20) { builder.cipherSuites( CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) } //Secure - Chrome 51 supports if (Build.VERSION.SDK_INT >= API_LEVEL_24) { builder.cipherSuites( CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) } Cipher Suits Network Security

Slide 13

Slide 13 text

The server must also support the TLS versions and the cipher suits. Check it with OpenSSL nmap -sV --script ssl-enum-ciphers -p 443 hostname Cipher Suits Network Security

Slide 14

Slide 14 text

Cipher Suits Network Security

Slide 15

Slide 15 text

Asymmetric crypto - Protection again Man-in-the-middle attacks Technically the public part of the server key e.q RSA (1) CA Certified certificate • CA is responsible for that • CA holds the cert and validates it (2) Self-signed certificate • Created by the server administrator • By default leads to an exception HTTPS - Authentication Network Security

Slide 16

Slide 16 text

To make sure we communicate with the right party Include the certificate into the app, and validate the server using it To get that certificate echo | openssl s_client -connect hostname:443 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p’ > hostname.pem Android handles BKS-V1 certs, use Portecle app to convert PEM to BKS-V1 HTTPS – Certificate pinning Network Security

Slide 17

Slide 17 text

HTTPS – Certificate pinning Network Security

Slide 18

Slide 18 text

private fun getTrustManagers(context: Context, keyStoreFile: Int, keystorePassword: String): Array { val trusted = KeyStore.getInstance("BKS") val rawResource = context.resources.openRawResource(keyStoreFile) trusted.load(rawResource, keystorePassword.toCharArray()) val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(trusted) return trustManagerFactory.trustManagers } HTTPS – Certificate pinning Network Security

Slide 19

Slide 19 text

@Throws(KeyStoreException::class, CertificateException::class, NoSuchAlgorithmException::class, IOException::class, KeyManagementException::class) fun getPinnedCertSocketFactory(context: Context, keyStoreFile: Int, keystorePassword: String, forceTls12: Boolean): SSLSocketFactory { val trustManagers = getTrustManagers(context, keyStoreFile, keystorePassword) val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, trustManagers, null) var socketFactory = sslContext.socketFactory if (forceTls12 && Build.VERSION.SDK_INT in 16..19) { socketFactory = ForceTlsSocketFactory(sslContext.socketFactory) } return socketFactory } HTTPS – Certificate pinning Network Security

Slide 20

Slide 20 text

Local Data Security

Slide 21

Slide 21 text

Where to store sensitive data? (1) Internal Storage - only accessible by the app Really? - What if allowBackup=true? (this is accessible with an adb command) Really? – What is the device is rooted? (2) External Storage Anyone can read and write that L But the internal one is limited , so sometimes we need it How to store sensitive data? Encrypt it! -> No one can read Authenticate it! -> Modification is detected! Storing sensitive data on the device Data Security

Slide 22

Slide 22 text

(1) Shared Preferences Encrypt the values by yourself -> See cryptography section! (2) Databases – SQL Use SQLCipher – Supports AES-256-CBC+HMAC_SHA1 val database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "password", null) (3) Databases – NoSQL Use Realm - Supports AES-256-GCM val realmConfiguration = RealmConfiguration.Builder().encryptionKey(key).build() (4) File storage Use Facebook Conceal – AES-256-GCM Secure Solutions for Storage Types Data Security

Slide 23

Slide 23 text

Cryptography

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Crypto is (also) fragmented! (e.q AES-256 is API26+) Android Crypto implementations Above the JVM: BouncyCastle Below the JVM: OpenSSL Different versions... ...different ciphers supported ...known vulnerabilities in older versions Solution: Include the BouncyCastle as a lib Package names will collide! -> Spongy Castle Implementations Cryptography

Slide 26

Slide 26 text

Repackaged version of Bouncy Castle Technically the same, but different packagename Different identifier – SC You can include the version you want – 1.58.0 is latest! Includes most of the available ciphers and algorithms Symmetric crypto e.g. AES – 128/256 – CBC/GCM Asymmetric crypto e.g. RSA, ECDSA, ECDHE Key derivation e.g. PBKDF2WithHmacSHA1, PBEWITHHMACSHA1 ... SpongyCastle Cryptography

Slide 27

Slide 27 text

Include the library: compile 'com.madgag.spongycastle:core:1.56.0.0' compile 'com.madgag.spongycastle:prov:1.56.0.0’ Register as a crypto provider class MyApplication : Application() { companion object { init { Security.insertProviderAt(BouncyCastleProvider(), 1) } } } Example: Generate keys for Realm Cryptography

Slide 28

Slide 28 text

Use PBDKF2 for Keys Use user input as password (e.q a string) – Do not store that Salt it with random number – Initialization Vector (IV) Save IV for later use fun generateRandom(lengthInBytes: Int): ByteArray { val random = SecureRandom.getInstance(“SHA1PRNG”) val genBytes = ByteArray(lengthInBytes) random.nextBytes(genBytes) return genBytes } Generate 256bit key for AES-256-GCM, And another 256bit key for HMAC fun deriveKey(password: String, iv: ByteArray): ByteArray { val iterationCount = 1000 val keySpec = PBEKeySpec(password.toCharArray(), iv, iterationCount, KEY_SIZE) val keyFactory = SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA1”) val keyBytes = keyFactory.generateSecret(keySpec).encoded return keyBytes } Example: Generate keys for Realm Cryptography

Slide 29

Slide 29 text

Passing it for Realm: fun provideRealm(context: Context, password: CharArray?): Realm { val config = RealmConfiguration.Builder() .name(DATABASE_NAME) .encryptionKey(getKeys(context, password)) .schemaVersion(1) .build() return Realm.getInstance(config) } private fun getKeys(context: Context, password: CharArray?): ByteArray { val manager = PasswordManager(context) if (!manager.isPasswordSet(AES_KEY)) { manager.setDerivedPassword(AES_KEY, password!!, 256) } if (!manager.isPasswordSet(HMAC_KEY)) { manager.setDerivedPassword(HMAC_KEY, password!!, 256) } var aesKey: ByteArray? = manager.getDerivedPassword(AES_KEY, password!!, 256) var hmacKey: ByteArray? = manager.getDerivedPassword(HMAC_KEY, password!!, 256) val fullKey: ByteArray = aesKey!!.plus(hmacKey!!) return fullKey } Example: Generate keys for Realm Cryptography

Slide 30

Slide 30 text

For networking Use HTTPS Specify the best TLS version and cipher suite Pin all certificates For local data Encrypt and authenticate Use libraries when possible For cryptography Package the latest Spongy Castle Use random IV and save it! Use PBDF2 for passwords Use AES-256-GCM for encryption Summary Secure Android Applications

Slide 31

Slide 31 text

http://nhprice.com/what-is-ios-model-the-overall-explanation-of-ios-7-layers.html https://developer.android.com/reference/javax/net/ssl/SSLSocket.html https://developer.android.com/about/dashboards/index.html http://square.github.io/okhttp/ https://realm.io/ https://www.zetetic.net/sqlcipher/sqlcipher-for-android/ https://rtyley.github.io/spongycastle/ References Secure Android Applications github.com/BaloghTamas [email protected]

Slide 32

Slide 32 text

github.com/BaloghTamas [email protected] Any questions? Thank you very much for your attention