droidconNL 2014 - Implementing Cryptography on Android

45
Funky Android Ltd. http://www.funkyandroid.com/ Implementing Cryptography on Android

Transcript of droidconNL 2014 - Implementing Cryptography on Android

Page 1: droidconNL 2014 - Implementing Cryptography on Android

Funky Android Ltd.http://www.funkyandroid.com/

Implementing Cryptography on Android

Page 2: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Why?

• Keep data secure - SSL is only for data on the move

• Easier than you might think.

Page 3: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Why?

• Keep data secure - SSL TLS is only for data on the move

• Easier than you might think.

Page 4: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Why?

• Keep data secure - Transport Layer Security is only for data on the move

• Easier than you might think.

Page 5: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Things to remember

• Perfect security isn’t currently feasible

• The aim is to make the “cost” of getting the data greater than the value of the data obtained.

• It’s up to you how much you want any attacker to have to “pay” to get your users data.

Page 6: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

What you need to know

Page 7: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

A key pair

• Asymmetric Cryptography.

• The private key is…. well…. private.

• The public key is where you want the data decrypted.

• Use the private key to encrypt the license, and the public key can decrypt it.

Page 8: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

A standard format

• Create one yourself

• You can use multiple forms of cryptography

• You can checksum blocks

Page 9: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Hidden decryption

• Decryption keys shouldn’t be easy to find.

• The more effort you put into hiding them, the harder it is to crack

• Think about using timestamped data that need refreshing.

Page 10: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Hidden decryption

Evading Pirates and Stopping Vampires

http://www.youtube.com/watch?v=TnSNCXR9fbY

Page 11: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Lots of data - PGP• Asymmetric

Cryptography tends to be relatively slow, so may not make sense for lots of data

• Asymmetrically Encrypt a “session key” - A new key for each encryption.

Diagram from Wikipedia - https://en.wikipedia.org/wiki/Pretty_Good_Privacy#mediaviewer/File:PGP_diagram.svg

Page 12: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Lots of data - PGP• Asymmetrically Encrypt

a checksum of the data encrypted using the session key

• Use AES encryption for speed.

Diagram from Wikipedia - https://en.wikipedia.org/wiki/Pretty_Good_Privacy#mediaviewer/File:PGP_diagram.svg

Page 13: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

AES/CBC/PKCS5Padding

• AES - Can encrypt blocks of data (1 block is 128 bits - 16 bytes)

• CBC - Cipher Block Chaining - One block relies on the previous block (Alternatives CFB, OFB, CTR, ECB)

• PKCS5Padding - Ensure blocks of data are the right size to be chained.

Page 14: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

CBC• Cipher-block chaining

• Each block relies on the previous one.

• IV required to start the process.

Diagram from WikiMedia - https://commons.wikimedia.org/wiki/File:CBC_encryption.svg

Page 15: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

CTR• Counter

• Encodes each with a counter

• Suitable for parallel encryption.

Diagram from WikiMedia - https://commons.wikimedia.org/wiki/File:CTR_encryption_2.svg

Page 16: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

ECB• Electronic codebook

• Encodes each block separately

• Not advised - Parallel attack possible.

Diagram from WikiMedia - https://commons.wikimedia.org/wiki/File:ECB_encryption.svg

Page 17: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

AES/CBC/PKCS5Padding

• AES - Can encrypt blocks of data (1 block is 128 bits - 16 bytes)

• CBC - Cipher Block Chaining - One block relies on the previous block (Alternatives CFB, OFB, CTR, ECB)

• PKCS5Padding - Ensure blocks of data are the right size to be chained.

Page 18: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

The Code

Page 19: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Key Generationimport java.security.*;

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

kpg.initialize(2048, new SecureRandom());

KeyPair keys = kpg.generateKeyPair();

* 2048 bit key because that’s the limit in Android 4.3 and before.

Page 20: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Key -> byte[ ]

PrivateKey privateKey = keys.getPrivate();

byte[] privBytes = privateKey.getEncoded();

PublicKey publicKey = keys.getPublic();

byte[] pubBytes = publicKey.getEncoded();

Page 21: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

byte[ ] -> Private Key

PKCS8EncodedKeySpec skeySpec = new PKCS8EncodedKeySpec(privBytes);

KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);

PrivateKey privateKey = keyFactory.generatePrivate(skeySpec);

Page 22: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Encrypt Data

Cipher cipher = Cipher.getInstance(“RSA”);

cipher.init(Cipher.ENCRYPT_MODE, privateKey);

byte[] encryptedData = cipher.doFinal(data);

Page 23: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

byte[ ] -> Public Key

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubBytes);

KeyFactory factory = KeyFactory.getInstance(“RSA");

PublicKey publicKey = factory.generatePublic(keySpec);

Page 24: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Decrypt Data

Cipher cipher = Cipher.getInstance(“RSA”);

cipher.init(Cipher.DECRYPT_MODE, publicKey);

byte[] data = cipher.doFinal(encryptedData);

Page 25: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

“Session Key”import java.security.*;

KeyGenerator keyGen = KeyGenerator.getInstance("AES");

keyGen.init(128);

SecretKey key = keyGen.generateKey();

* 128 bit key because that’s Oracle’s default maximum AES key length.

Page 26: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

key -> byte [ ]

byte[] sessionKeyBytes = key.getEncoded()

Page 27: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

byte[ ] -> key

SecretKeySpec skeySpec =  new SecretKeySpec(sessionKeyBytes, "AES"); 

Page 28: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Encrypt Data

Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

byte[] encryptedData = cipher.doFinal(data);

byte[] initialisationVector = cipher.getIV();

Page 29: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Decrypt DataCipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”);

cipher.init( Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec( initialisationVector ) );

byte[] data = cipher.doFinal(encryptedData);

Page 30: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Passwords

Page 31: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Passwords

• Don’t store passwords in clear text

• Store something made from the password that can’t be used to get the password

• One of the oldest problems of multi-user systems and the solutions have been widely tested

Page 32: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Using Hash

• A Hash function takes some bytes and generates some bytes

• “One way” - Designed so you can’t get the original bytes from the generated bytes.

Page 33: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Getting Hash

MessageDigest digester = MessageDigest.getInstance(“SHA-256“);

byte[] passwordBytes = password.getBytes(“UTF-8”);

byte[] hash = digester.digest(passwordBytes);

Page 34: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Bad Rainbow (tables)• Rainbow Tables - A Map of pre-calculated

hashes

• The hash is the key, the original password is the value

• The more hash you have, the bigger the rainbow.

• The bigger the rainbow, the longer it takes to look for the answer.

Page 35: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Salting your hash

• Salt - Some random bytes to make dictionary based rainbow tables less useful.

• Add the randomness to the start of the password

• Store the salt so you can re-create the hashed value

Page 36: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Adding the saltbyte[] passwordBytes = password.getBytes(“UTF-8”);

byte[] salt = new byte[SALT_SIZE];

int saltedPasswordSize = passwordBytes.length + SALT_SIZE;

byte[] saltedPassword = new byte[saltedPasswordSize];

Page 37: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Adding the saltSecureRandom saltGenerator = new SecureRandom();

saltGenerator.nextBytes(salt);

System.arraycopy( passwordBytes, 0, saltedPassword, 0, passwordBytes.length ); System.arraycopy( salt, 0, saltedPassword, passwordBytes.length, SALT_SIZE );

Page 38: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Getting Salted Hash

MessageDigest digester = MessageDigest.getInstance(“SHA-256“);

byte[] hash = digester.digest(saltedPassword);

Page 39: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Getting Hash

MessageDigest digester = MessageDigest.getInstance(“SHA-256“);

byte[] passwordBytes = password.getBytes(“UTF-8”);

byte[] hash = digester.digest(passwordBytes);

Page 40: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Getting Salted Hash

MessageDigest digester = MessageDigest.getInstance(“SHA-256“);

byte[] hash = digester.digest(saltedPassword);

Page 41: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Keeping Salted Hashbyte[] storedSaltedHash = new byte[SALT_SIZE + hash.length];

System.arraycopy( salt, 0, storedSaltedHash, 0, SALT_SIZE ); System.arraycopy( hash, 0, storedSaltedHash, SALT_SIZE, hash.length );

Page 42: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Putting it together

Page 43: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Password Based Encryption

• Use the password as the encryption key

• Check the password entered with a stored, salted, hash.

• Use an algorithm such as PBKDF2 to create the key.

Page 44: droidconNL 2014 - Implementing Cryptography on Android

www.funkyandroid.com

Password Based Encryption

• How to do it : http://nelenkov.blogspot.nl/2012/04/using-password-based-encryption-on.html

• Hardware has advanced, use more iterations.

• Information published after the article : http://goo.gl/JEkbR0 http://goo.gl/0icI3Q

Page 45: droidconNL 2014 - Implementing Cryptography on Android

Funky Android Ltd.http://www.funkyandroid.com/

Questions ?