6. Android Security
Key Management
Cryptography in Mobile
Applications
● Protect data
○ Sensitive data
○ Data on /sdcard
○ Cryptographic material
● Exchange data securely
○ Documents
○ Mail
○ SMS
○ Session Keys
● Digital Signature
○ Documents
○ Mail
8. Android Security
Key Management
CryptoSystem
"refers to a suite of algorithms needed to implement a particular
form of encryption and decryption"
●
● Two types of encryption:
○ Symmetric Key Algorithms
■ Identical encryption key for
encryption/decryption
■ AES, Blowfish, DES, Triple DES
○ Asymmetric Key Algorithms
■ Different key for
encryption/decryption
■ RSA, DSA, ECDSA
9. Android Security
Key Management
Ciphers
● Two types of ciphers:
○ Block: Process entire blocks of fixed-length
groups of bits at a time ( padding may be
required)
○ Stream: Process single byte at a time ( no
padding )
● Block Cipher modes of operation
○ ECB: each block encrypted independently
○ CBC, CFB, OFB: the previous block of
output is used to alter the input blocks
before applying the encryption algorithm
starting from a IV ( initialization vector )
10. Android Security
Key Management
Crypto in Android
● Based on JCA ( Java
Cryptographic Architecture)
provides API for:
● Encryption/Decryption
● Digital signatures
● Message digests (hashes)
● Key management
● Secure random number
generation
● “Provider” Architecture with CSP
● Bouncy Castle is Android default
CSP
11. Android Security
Key Management
Bouncy Castle Android Version
● Customized:
○ Some services and API removed
● Varies between Android versions
● Fixed only in the latest versions
● Solution: Spongy Castle
● Repackage of Bouncy Castle
● Supports more cryptographic options
● Up-to-date
● Not vulnerable to the Heartbleed Bug
(CVE-2014-0160)
20. Android Security
Key Management
SecretKey Specification
javax.crypto.spec.SecretKeySpec
● SecretKeySpec specifies a key for a specific algorithm
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Topic of this workshop
Cryptographic Algorithm
21. Android Security
Key Management
Cipher GetInstance
javax.crypto.Cipher
● Provides access to implementations of cryptographic ciphers
for encryption and decryption
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding”,“SC”);
Trasformation
(describes set of operation to
perform):
• algorithm/mode/padding
• algorithm
Provider
( SpongyCastle )
22. Android Security
Key Management
Cipher Init
javax.crypto.Cipher
● Initializes the cipher instance with the specified operational
mode, key and algorithm parameters.
cipher.init(Cipher.DECRYPT_MODE, keySpec,
new IvParameterSpec(iv));
Operational Mode:
• ENCRYPT_MODE
• DECRYPT_MODE
• WRAP_MODE
• UNWRAP_MODE
SecretKeySpec Specify Cipher
Algorithm parameters
( IV for CBC )
23. Android Security
Key Management
Cipher Final
javax.crypto.Cipher
● Finishes a multi-part transformation (encryption or decryption)
byte[] encryptedText = cipher.doFinal(clearText.getBytes());
Encrypted
Text in byte
ClearText in
bytes
25. Android Security
Key Management
SecureRandom
java.security.SecureRandom
● Cryptographically secure pseudo-random number generator
SecureRandom secureRandom = new SecureRandom();
Default constructor uses the
most cryptographically
strong provider available
● Seeding
SecureRandom is
dangerous:
○ Not Secure
○ Output may change
26. Android Security
Key Management
Some SecureRandom
Thoughts...
● Android security team discovered a JCA improper PRNG
initialization in August 2013
● Applications invoking system-provided OpenSSL PRNG without
explicit initialization are also affected
● Key Generation, Signing or Random Number Generation not
receiving cryptographically strong values
● Developer must explicitly initialize the PRNG
PRNGFixes.apply()
27. Android Security
Key Management
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES”,“SC”);
keyGenerator.init(outputKeyLength, secureRandom);
SecretKey key = keyGenerator.generateKey();
Generate Secret Key
javax.crypto.KeyGenerator
● Symmetric cryptographic keys generator API
Specify Key Size
Algorithm
and Provider
Key to use in Cipher.init()
28. Android Security
Key Management
Key Management: Store on
device
● Protected by Android Filesystem Isolation
● Plain File
● SharedPreferences
● Keystore File (BKS, JKS)
● More secure with Phone Encryption
● Store safely
○ MODE_PRIVATE flag
○ Use only internal storage
/data/data/app_package
31. Android Security
Key Management
Key Management: Store in App
● Uses static keys or device specific information at run-time (IMEI, mac
address, ANDROID_ID)
● Android app can be easily reversed ( live demo )
● Hide with Code obfuscation
● Security by Obscurity is never a good idea...
34. Android Security
Key Management
Key Management: PBKDF2
● Password Based Key Derivation Function (PKCS#5)
● Variable length password in input
● Fixed length key in output
● User interaction required
● Params:
○ Password
○ Pseudorandom Function
○ Salt
○ Number of iteration
○ Key Size
35. Android Security
Key Management
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
NUM_OF_ITERATIONS, KEY_SIZE);
SecretKeyFactory secretKeyFactory =
SecretKeyFactory.getInstance(PBE_ALGORITHM);
encKey = secretKeyFactory.generateSecret(keySpec);
Key Management: PBKDF2
javax.crypto.spec.PBEKeySpec
● PBE Key specification and generation
A good PBE algorithm is
PBKDF2WithHmacSHA1
User
Password
N. >= 1000
36. Android Security
Key Management
SecretKeyFactory factory;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
// Use compatibility key factory -- only uses lower 8-bits of passphrase chars
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1And8bit");
else if (Build.VERSION.SDK_INT >= 10)
// Traditional key factory. Will use lower 8-bits of passphrase chars on
// older Android versions (API level 18 and lower) and all available bits
// on KitKat and newer (API level 19 and higher)
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
else // FIX for Android 8,9
factory = SecretKeyFactory.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
SecretKeyFactory API in
Android 4.4
38. Android Security
Key Management
Key Management: Other
solutions
● Store on server side
● Internet connection required
● Use trusted and protected connections (HTTPS, Certificate
Pinning)
● Store on external device
○ NFC Java Card (NXP J3A081)
○ Smartcard
○ USB PenDrive
○ MicroSD with secure storage
● AndroidKeyStore???
39. Android Security
Key Management
Asymmetric Algorithms
● Public/Private Key
○ Public Key -> encrypt/verify signature
○ Private Key -> decrypt/sign
● Advantages:
○ Public Key distribution is not dangerous
● Disadvantages:
○ Computationally expensive
● Usually used with PKI (Public Key Infrastructure for digital
certificates)
40. Android Security
Key Management
Public-key Applications
● Can classify uses into 3 categories:
○ Encryption/Decryption (provides confidentiality)
○ Digital Signatures (provides authentication and Integrity)
○ Key Exchange (of session keys)
● Some algorithms are suitable for all uses (RSA),
others are specific to one
41. Android Security
Key Management
PKCS for Asymmetric
Algorithms
● PKCS is a group of public-key cryptography
standards published by RSA Security Inc
● PKCS#1 (v.2.1)
○ RSA Cryptography Standard
● PKCS#3 (v.1.4)
○ Diffie-Hellman Key Agreement Standard
● PKCS#8 (v.1.2)
○ Private-Key Information Syntax Standard
● PKCS#10 (v.1.7)
○ Certification Request Standard
● PKCS#12 (v.1.0)
○ Personal Information Exchange Syntax Standard
42. Android Security
Key Management
Android: RSA
KeyPairGenerator kpg =
KeyPairGenerator.getIstance(”RSA");
Java.security.KeyPairGenerator
● KeyPairGenerator is an engine capable of
generating public/private keys with specified
algorithms
Cryptographic Algorithm
43. Android Security
Key Management
Available Providers for RSA
Algorithm
KeyPairGenerator.getInstance(”RSA”,”SEC_PROVIDERS”);
Java.security.KeyPairGenerator
● Different security providers could be used (could
change for different OS versions)
“AndroidOpenSSL”
“BC”
“AndroidKeyStrore”
Version 1.0
Version 1.49
Version 1.0
44. Android Security
Key Management
● KeySize – 1024,2048,4096 bits
KeyPairGenerator: Initialization
and Randomness
KeyPairGenerator kpg =
KeyPairGenerator.initialize(2048);
Java.security.KeyPairGenerator
● KeyPairGenerator initialization with the key size
Key Size
45. Android Security
Key Management
KeyPairGenerator: Initialization
and Randomness
KeyPairGenerator kpg =
KeyPairGenerator.initialize(2048,sr);
Java.security.KeyPairGenerator, Java.security.SecureRandom
● KeyPairGenerator initialization with a
SecureRandom
SecureRandom sr = new SecureRandom();
46. Android Security
Key Management
Generating RSA Key
Java.security.KeyPair
● KeyPair is a container for a public/private key
generated by the KeyPairGenerator
KeyPair keypair = kpg.genKeyPair()
● We can retrieve public/private keys from KeyPair
Key public_key = kaypair.getPublic();
Key private_key = kaypair.getPrivate();
47. Android Security
Key Management
Using RSA Keys: cipher
example
Javax.crypto.Cipher
● Cipher provides access to implementation of
cryptography ciphers for encryption and decryption
Cipher cipher = Cipher.getInstance(“RSA”,”SEC_PROVIDER);
Transformation
“AndroidOpenSSL”
“BC”
“AndroidKeyStrore”
50. Android Security
Key Management
Extract Parameters of RSA
Keys
Java.security.spec.RSAPublicKeySpec, java.security.spec.RSAPrivateKeySpec
● Retrieved parameters can be stored
BigInteger m = rsa_public.getModulus();
BigInteger e = rsa_public.getPublicExponent();
BigInteger d = rsa_private.getPrivateExponent();
Is Private
52. Android Security
Key Management
AndroidKeyStore
● Custom Java Security Provider available from Android 4.3
version and beyond
● An App can generate and save private keys
● Keys are private for each App
● 2048-bit key size (4.3), 1024-2048-4096-bit key size (4.4) can
be stored
● ECDSA support added from Android 4.4
53. Android Security
Key Management
Key Management Evolution
API LEVEL 14 API LEVEL 18
Global Level:
KeyChain
( Public API )
App Level:
KeyStore
( Closed API )
Global Level Only:
Default TrustStore
cacerts.bks
(ROOTED device)
Global Level:
KeyChain
( Public API )
App Level and
per User Level:
AndroidKeyStore
( Public API )
54. Android Security
Key Management
AndroidKeyStore Storage
● Two kinds of storage
○ Hardware-backed (Nexus 7, Nexus
4, Nexus 5 :-) with OS >= 4.3)
○ Secure Element
○ TPM
○ TrustZone
○ Software only (Other devices with
OS >= 4.3)
55. Android Security
Key Management
Type of Storage
import android.security.KeyChain;
if (KeyChain.isBoundKeyAlgorithm("RSA"))
// Hardware-Backed
else
// Software Only
56. Android Security
Key Management
Certificate parameters
Context cx = getActivity();
String pkg = cx.getPackageName();
Calendar notBefore = Calendar.getInstance();
Calendar notAfter = Calendar.getInstance();
notAfter.add(1, Calendar.YEAR);
import android.security.KeyPairGeneratorSpec.Builder;
Builder builder = new KeyPairGeneratorSpec.Builder(cx);
builder.setAlias(“DEVKEY1”);
String infocert = String.format("CN=%s, OU=%s", “DEVKEY1”, pkg);
builder.setSubject(new X500Principal(infocert));
builder.setSerialNumber(BigInteger.ONE);
builder.setStartDate(notBefore.getTime());
builder.setEndDate(notAfter.getTime());
KeyPairGeneratorSpec spec = builder.build();
Times parameters
Self-Signed X.509
● Common Name (CN)
● Subject (OU)
● Serial Number
Generate certificate
ALIAS to index the
certificate
57. Android Security
Key Management
Generating Public/Private keys
KeyPairGenerator kpGenerator;
kpGenerator = KeyPairGenerator
.getInstance("RSA", "AndroidKeyStore");
kpGenerator.initialize(spec);
KeyPair kp;
kp = kpGenerator.generateKeyPair();
Engine to generate
Public/Private key
Init Engine with:
● RSA Algorithm
● Provider: AndroidKeyStore
Init Engine with certificate parameters
After generation, the keys will be stored into AndroidKeyStore and will be
accessible by ALIAS
● Generating Private/Public key
58. Android Security
Key Management
AndroidKeyStore Initialization
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
Now we have the KeyStore reference that will be used to
access to the Private/Public key by the ALIAS
Should be used if there is an InputStream to load
(for example the name of imported KeyStore). If not
used the App will crash
Get a reference to the AndroidKeyStore
60. Android Security
Key Management
RSA Digital Signature
● Digital Signature
○ Authentication, Non-Repudiation and Integrity
○ RSA Private key to Sign
○ RSA Public Key to Verify
KeyStore.Entry entry = ks.getEntry(“DEVKEY1”, null);
byte[] data = “GDG-Meets-U 2014!”.getBytes();
Signature s = Signature.getInstance(“SHA256withRSA”);
s.initSign(((KeyStore.PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();
String result = null;
result = Base64.encodeToString(signature, Base64.DEFAULT);
Access to Private/Public key identified
by ALIAS
Algorithm choice
Private key to sign
Signature and Base64
encoding
61. Android Security
Key Management
Verify RSA Digital Signature
byte[] data = input.getBytes();
byte[] signature;
signature = Base64.decode(signatureStr, Base64.DEFAULT);
KeyStore.Entry entry = ks.getEntry(“DEVKEY1”, null);
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(((KeyStore.PrivateKeyEntry) entry).getCertificate());
s.update(data);
boolean valid = s.verify(signature);
Base64 decoding
Access to the Private/Public key
identified by ALIAS==DEVKEY1
Algorithm choice
Public Key in certificate to
verify signature
TRUE == Verified
FALSE== Not Verified
66. Android Security
Key Management
It is observed that...
● Different screen lock
● The choice of screen lock
impactsthe keys
● If you change the screen lock the
keys are deleted
67. Android Security
Key Management
Expected behavior?
● The official documentation shows:
● The keys should ramain intact when the type of screen lock is
changed by the user
71. Android Security
Key Management
Example: Import Certificates
● Import .p12 certificates
Intent intent = KeyChain.createInstallIntent();
byte[] p12 = readFile(“CERTIFICATE_NAME.p12”);
Intent.putExtra(KeyChain.EXTRA_PKCS12,p12);
Specify PKCS#12 Key to install
startActivity(intent);
The user will be
prompted for the
password
72. Android Security
Key Management
KeyChain.choosePrivateKeyAlias(
Activity activity,
KeyChainAliasCallBack response,
String[] keyTypes,
Principal[] issuers,
String host,
Int port,
String Alias);
Example: Retrieve the key
● The KeyChainAliasCallback invoked when a user chooses a
certificate/private key
73. Android Security
Key Management
@Override
public void alias(String alias){
.
.
PrivateKey private_key = KeyChain.
getPrivateKey(this,alias);
.
.
X509Certificate[] chain = KeyChain.
getCertificateChain(this,”Droidcon”);
.
PublicKey public_key = chain[0].getPublicKey();
}
Example: Retrieve and use the
keys
● KeyChainAliasCallbak must implement the abstract method
alias:
Private Key
Public Key