13
Secure- preferences https://github.com/scottyab/secure-preferences Jain Newegg developer

Secure preferences

Embed Size (px)

Citation preview

Page 1: Secure preferences

Secure-preferenceshttps://github.com/scottyab/secure-preferences

JainNewegg developer

Page 2: Secure preferences

What is SharedPreferences

• Save and retrieve persistent key-value pairs of primitive data types

• Save any primitive data: booleans, floats, ints, longs, and strings

Page 3: Secure preferences

Why use Secure-preferences

• Protect secret data1.password2.token3.setting

Page 4: Secure preferences

Secure mechanism• Encrypts the values using AES 128, CBC, and

PKCS5

• Each key is stored as a one way SHA 256 hash

• Both keys and values are base64 encoded before storing into prefs xml file

Page 5: Secure preferences

Secure data

Page 6: Secure preferences

How to usepublic SharedPreferences getSharedPreferences() { if(mSecurePrefs==null){ mSecurePrefs = new SecurePreferences(this, "", "my_prefs.xml"); SecurePreferences.setLoggingEnabled(true); } return mSecurePrefs;}

Page 7: Secure preferences

public SharedPreferences getSharedPreferences1000() { try { AesCbcWithIntegrity.SecretKeys myKey = AesCbcWithIntegrity.generateKeyFromPassword( Build.SERIAL,AesCbcWithIntegrity.generateSalt(),1000); return new SecurePreferences(this, myKey, "my_prefs_1000.xml"); } catch (GeneralSecurityException e) { Log.e(TAG, "Failed to create custom key for SecurePreferences", e); } return null;}

How to usepublic SharedPreferences getSharedPreferences() { if(mSecurePrefs==null){ mSecurePrefs = new SecurePreferences(this, "", "my_prefs.xml"); SecurePreferences.setLoggingEnabled(true); } return mSecurePrefs;}

Page 8: Secure preferences

How to usepublic SharedPreferences getSharedPreferences() { if(mSecurePrefs==null){ mSecurePrefs = new SecurePreferences(this, "", "my_prefs.xml"); SecurePreferences.setLoggingEnabled(true); } return mSecurePrefs;}

public SharedPreferences getSharedPreferences1000() { try { AesCbcWithIntegrity.SecretKeys myKey = AesCbcWithIntegrity.generateKeyFromPassword( Build.SERIAL,AesCbcWithIntegrity.generateSalt(),1000); return new SecurePreferences(this, myKey, "my_prefs_1000.xml"); } catch (GeneralSecurityException e) { Log.e(TAG, "Failed to create custom key for SecurePreferences", e); } return null;}

public SecurePreferences getUserPinBasedSharedPreferences(String password){ if(mUserPrefs==null) { mUserPrefs = new SecurePreferences(this, password, "user_prefs.xml"); } return mUserPrefs;}

Page 9: Secure preferences

public void onGetButtonClick(View v) {final String value = getSharedPref().getString(MainActivity.KEY, null);

toast(MainActivity.KEY + "'s, value= " + value);}

public void onSetButtonClick(View v) {getSharedPref().edit().putString(MainActivity.KEY, MainActivity.VALUE)

.commit();toast(MainActivity.KEY + " with enc value:" + MainActivity.VALUE

+ ". Saved");}

public void onRemoveButtonClick(View v) {getSharedPref().edit().remove(MainActivity.KEY).commit();

toast("key:" + MainActivity.KEY + " removed from secure prefs");}

public void onClearAllButtonClick(View v) {getSharedPref().edit().clear().commit();updateEncValueDisplay();

toast("All secure prefs cleared");}

Page 10: Secure preferences

Put valueputString(String key, String value)

hashPrefKey(String prefKey)

encrypt(String cleartext)

encrypt(byte[] plaintext, SecretKeys secretKeys)

new CipherTextIvMac(byteCipherText, iv, integrityMac)

toString()public static CipherTextIvMac encrypt(byte[] plaintext, SecretKeys secretKeys) throws GeneralSecurityException { byte[] iv = generateIv(); Cipher aesCipherForEncryption = Cipher.getInstance(CIPHER_TRANSFORMATION); aesCipherForEncryption.init(Cipher.ENCRYPT_MODE, secretKeys.getConfidentialityKey(), new IvParameterSpec(iv)); /* * Now we get back the IV that will actually be used. Some Android * versions do funny stuff w/ the IV, so this is to work around bugs: */ iv = aesCipherForEncryption.getIV(); byte[] byteCipherText = aesCipherForEncryption.doFinal(plaintext); byte[] ivCipherConcat = CipherTextIvMac.ivCipherConcat(iv, byteCipherText); byte[] integrityMac = generateMac(ivCipherConcat, secretKeys.getIntegrityKey()); return new CipherTextIvMac(byteCipherText, iv, integrityMac);}

Page 11: Secure preferences

putString(String key, String value)

hashPrefKey(String prefKey)

encrypt(String cleartext)

encrypt(byte[] plaintext, SecretKeys secretKeys)

new CipherTextIvMac(byteCipherText, iv, integrityMac)

toString()public String toString() { String ivString = Base64.encodeToString(iv, BASE64_FLAGS); String cipherTextString = Base64.encodeToString(cipherText, BASE64_FLAGS); String macString = Base64.encodeToString(mac, BASE64_FLAGS); return String.format(ivString + ":" + macString + ":" + cipherTextString);}

Put value

Page 12: Secure preferences

Get valuegetInt(String key, int defaultValue)

decrypt(final String ciphertext)

new AesCbcWithIntegrity.CipherTextIvMac(ciphertext)

decryptString(cipherTextIvMac, keys)

public static byte[] decrypt(CipherTextIvMac civ, SecretKeys secretKeys) throws GeneralSecurityException { byte[] ivCipherConcat = CipherTextIvMac.ivCipherConcat(civ.getIv(), civ.getCipherText()); byte[] computedMac = generateMac(ivCipherConcat, secretKeys.getIntegrityKey()); if (constantTimeEq(computedMac, civ.getMac())) { Cipher aesCipherForDecryption = Cipher.getInstance(CIPHER_TRANSFORMATION); aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secretKeys.getConfidentialityKey(), new IvParameterSpec(civ.getIv())); return aesCipherForDecryption.doFinal(civ.getCipherText()); } else { throw new GeneralSecurityException("MAC stored in civ does not match computed MAC."); }}

new String(decrypt(civ, secretKeys), encoding)

Page 13: Secure preferences

Q & A