suite of algorithms needed to implement a particular form of encryption and decryption" • Two types of encryption: ◦ Symmetric Key Algorithms ▪ Identical key for encryption/decryption ▪ AES, Blowfish, DES, Triple DES ◦ Asymmetric Key Algorithms ▪ Pair of keys (public/private) for encryption/decryption ▪ RSA, DSA, ECDSA
• Two types of ciphers: ◦ Block: Process entire blocks of fixed-length groups of bits at a time (padding may be required) ◦ Stream: Process single bit at a time(no padding) • Block Cipher modes of operation: ◦ ECB: each block encrypted independently ◦ CBC, CFB, OFB: (feedback mode) each block is encrypted combined with the previous encrypted block (starting from an IV) ◦ CTR: each block xored with the encrypted successive values of a counter ( starting from a nonce) ECB CBC
Framework based on JCA ( Java Cryptography Architecture) • Provides API for: • Encryption/Decryption • Message digests (hashes) • Key management • Secure random number generation • API implemented by Cryptographic Service "Provider" • "Dynamic" Provider: javax.crypto.* java.security.*
the beginning ◦ Bouncy Castle (Customized): ▪ Some services and API removed ▪ Varies between Android versions ▪ Fixed only in the latest versions ◦ Crypto (Apache Harmony) ▪ Few basic services ▪ Only for backward compatibility ➢ From Android 4.0 ◦ AndroidOpenSSL: ▪ OpenSSL JNI ▪ Performance Improved ▪ Vulnerable to Heartbleed in 4.1.1
◦ Repackage of Bouncy Castle ◦ Supports more cryptographic options ◦ Not vulnerable to the Heartbleed Bug ◦ Up-to-date ➢ GPS Dynamic Security Provider ◦ Available from Play Services 5.0 ◦ Based on OpenSSL ( No Heartbleed) ◦ Rapid delivery of security patches ◦ Vendor independent !!! Dynamic Providers
SecretKeySpec specifies a key for a specific algorithm SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Encryption/Decryption Key Cryptographic Algorithm
Complete a multi-part transformation (encryption or decryption) byte[] encryptedText = cipher.doFinal(clearText.getBytes()); Encrypted Text in byte ClearText in bytes
• 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
Android security team discovered in August 2013 an improper PRNG initialization for default OpenSSL provider • 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() http://android-developers.blogspot.it/2013/08/some-securerandom-thoughts.html
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
App • Uses static keys or device specific information at run-time (IMEI, mac address, ANDROID_ID) • Android app can be easily reversed • Hide with Code obfuscation REVERSING
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 • Available with BC
>= 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
• 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???
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)
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
• 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
= KeyPairGenerator.getIstance(”RSA"); Java.security.KeyPairGenerator • KeyPairGenerator is an engine capable of generating public/private keys with specified algorithms Cryptographic Algorithm
Algorithm KeyPairGenerator.getInstance(”RSA”,”SEC_PROVIDERS”); Java.security.KeyPairGenerator • Different security providers could be used (could change for different OS versions) “AndroidOpenSSL” “BC” “AndroidKeyStore” “GmsCore_OpenSSL” Version 1.0 Version 1.49 Version 1.0
KeyPairGenerator kpg = KeyPairGenerator.initialize(2048,sr); Java.security.KeyPairGenerator, Java.security.SecureRandom • KeyPairGenerator initialization with a SecureRandom SecureRandom sr = new SecureRandom();
• 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();
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” “AndroidKeyStore” “GmsCore_OpenSSL”
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
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
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 )
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)
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
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
◦ Confidentiality ◦ RSA Public key to Encrypt ◦ RSA Private key to Decrypt KeyStore.Entry entry = keyStore.getEntry(“DEVKEY1”, null); PublicKey publicKeyEnc = ((KeyStore.PrivateKeyEntry) entry) .getCertificate().getPublicKey(); String textToEncrypt = new String(”DroidconUK-2014"); Cipher encCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); encCipher.init(Cipher.ENCRYPT_MODE, publicKeyEnc); byte[] encryptedText = encCipher.doFinal(byteTextToEncrypt); Access to Public key to encrypt • Algorithm • Encryption with Public key Ciphered Access to keys identified by ALIAS
valid = s.verify(signature); RSA Digital Signature • Digital Signature ◦ Authentication, Non-Repudiation and Integrity ◦ RSA Private key to Sign ◦ RSA Public Key to Verify KeyStore.Entry entry = keyStore.getEntry(“DEVKEY1”, null); s.initSign(((KeyStore.PrivateKeyEntry) entry).getPrivateKey()); Access to Private/Public key identified by ALIAS Private key to sign Public Key in certificate to verify signature
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
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