droidconNL 2014 - Implementing Cryptography on Android
-
Upload
al-sutton -
Category
Technology
-
view
545 -
download
1
Transcript of droidconNL 2014 - Implementing Cryptography on Android
Funky Android Ltd.http://www.funkyandroid.com/
Implementing Cryptography on Android
www.funkyandroid.com
Why?
• Keep data secure - SSL is only for data on the move
• Easier than you might think.
www.funkyandroid.com
Why?
• Keep data secure - SSL TLS is only for data on the move
• Easier than you might think.
www.funkyandroid.com
Why?
• Keep data secure - Transport Layer Security is only for data on the move
• Easier than you might think.
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.
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.
www.funkyandroid.com
A standard format
• Create one yourself
• You can use multiple forms of cryptography
• You can checksum blocks
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.
www.funkyandroid.com
Hidden decryption
Evading Pirates and Stopping Vampires
http://www.youtube.com/watch?v=TnSNCXR9fbY
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
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
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.
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
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
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
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.
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.
www.funkyandroid.com
Key -> byte[ ]
PrivateKey privateKey = keys.getPrivate();
byte[] privBytes = privateKey.getEncoded();
PublicKey publicKey = keys.getPublic();
byte[] pubBytes = publicKey.getEncoded();
www.funkyandroid.com
byte[ ] -> Private Key
PKCS8EncodedKeySpec skeySpec = new PKCS8EncodedKeySpec(privBytes);
KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);
PrivateKey privateKey = keyFactory.generatePrivate(skeySpec);
www.funkyandroid.com
Encrypt Data
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptedData = cipher.doFinal(data);
www.funkyandroid.com
byte[ ] -> Public Key
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubBytes);
KeyFactory factory = KeyFactory.getInstance(“RSA");
PublicKey publicKey = factory.generatePublic(keySpec);
www.funkyandroid.com
Decrypt Data
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] data = cipher.doFinal(encryptedData);
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.
www.funkyandroid.com
key -> byte [ ]
byte[] sessionKeyBytes = key.getEncoded()
www.funkyandroid.com
byte[ ] -> key
SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
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();
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);
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
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.
www.funkyandroid.com
Getting Hash
MessageDigest digester = MessageDigest.getInstance(“SHA-256“);
byte[] passwordBytes = password.getBytes(“UTF-8”);
byte[] hash = digester.digest(passwordBytes);
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.
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
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];
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 );
www.funkyandroid.com
Getting Salted Hash
MessageDigest digester = MessageDigest.getInstance(“SHA-256“);
byte[] hash = digester.digest(saltedPassword);
www.funkyandroid.com
Getting Hash
MessageDigest digester = MessageDigest.getInstance(“SHA-256“);
byte[] passwordBytes = password.getBytes(“UTF-8”);
byte[] hash = digester.digest(passwordBytes);
www.funkyandroid.com
Getting Salted Hash
MessageDigest digester = MessageDigest.getInstance(“SHA-256“);
byte[] hash = digester.digest(saltedPassword);
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 );
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.
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