Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Overview

Secure-preferences - Deprecated

  • Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active maintainers Secure-preferences)

This is Android Shared preference wrapper that encrypts the values of Shared Preferences using AES 128, CBC, and PKCS5 padding with integrity checking in the form of a SHA 256 hash. Each key is stored as a one way SHA 256 hash. Both keys and values are base64 encoded before storing into prefs xml file. By default the generated key is stored in the backing preferences file and so can be read and extracted by root user. Recommend use the user password generated option as added in v0.1.0.

The sample app is available on playstore

Sample app Screenshot

Release v0.1.0+

The v0.1.0 release was a major refactor of the guts of secure prefs, which is Not backwards compatible yet with older 0.0.1 - 0.0.4 versions. So if you have an existing app using this don't upgrade. I'll be looking to add migration into a later release.

Full list of changes

Usage

Dependency

Maven central is the preferred way:

Note: v0.1.0 was dependent on snapshot of aes-crypto, this is only as I was waiting for the aes-crypto repo owner to upload to maven. I've sorted this for v0.1.1+ which is no longer dependent on Snapshot repo.

dependencies {
    implementation 'com.scottyab:secure-preferences-lib:0.1.7'
}

Download

Or download the release .aar or clone this repo and add the library as a Android library project/module.

ProGuard config

As of v0.1.4 no specific -keep config is needed.

DexGuard

There is specific DexGuard config supplied with DexGuard 7+ located <dexgaurd root>/samples/advanced/SecurePreferences

Examples

This will use the default shared pref file

SharedPreferences prefs = new SecurePreferences(context);     

Custom pref file

You can define a separate file for encrypted preferences.

SharedPreferences prefs = new SecurePreferences(context, null, "my_custom_prefs.xml");

User password - (recommended)

Using a password that the user types in that isn't stored elsewhere in the app passed to the SecurePreferences constructor means the key is generated at runtime and not stored in the backing pref file.

SharedPreferences prefs = new SecurePreferences(context, "userpassword", "my_user_prefs.xml");

Changing Password

SecurePreferences securePrefs = new SecurePreferences(context, "userpassword", "my_user_prefs.xml");
securePrefs.handlePasswordChange("newPassword", context);

What does the data look like?

SharedPreferences keys and values are stored as simple map in an XML file. You could also use a rooted device and an app like cheatdroid

XML using Standard Android SharedPreferences

<map>
    <int name="timeout" value="500" />
    <boolean name="is_logged_in" value="true" />
</map>

XML with SecurePreferences

<map>
    <string name="TuwbBU0IrAyL9znGBJ87uEi7pW0FwYwX8SZiiKnD2VZ7">
        pD2UhS2K2MNjWm8KzpFrag==:MWm7NgaEhvaxAvA9wASUl0HUHCVBWkn3c2T1WoSAE/g=rroijgeWEGRDFSS/hg
    </string>
    <string name="8lqCQqn73Uo84Rj">k73tlfVNYsPshll19ztma7U">
        pD2UhS2K2MNjWm8KzpFrag==:MWm7NgaEhvaxAvA9wASUl0HUHCVBWkn3c2T1WoSAE/g=:jWm8KzUl0HUHCVBWkn3c2T1WoSAE/g=
    </string>
</map>

Disclaimer

By default it's not bullet proof security (in fact it's more like obfuscation of the preferences) but it's a quick win for incrementally making your android app more secure. For instance it'll stop users on rooted devices easily modifying your app's shared prefs. Recommend using the user password based prefs as introduced in v0.1.0.

Contributing

Please do send me pull requests, but also bugs, issues and enhancement requests are welcome please add an issue.

Licence

Much of the original code is from Daniel Abraham article on codeproject. This project was created and shared on Github with his permission.

Apache License, Version 2.0

Copyright (C) 2013, Daniel Abraham, Scott Alexander-Bown

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

The sample app Lock icon for sample app licenced under Creative Commons created by Sam Smith via thenounproject.com

Comments
  • Crashing in API 28 (Android Pie) s== null (DO NOT USE THIS LIBRARY, it is completely broken)

    Crashing in API 28 (Android Pie) s== null (DO NOT USE THIS LIBRARY, it is completely broken)

    2019-01-19 13:02:09.533 3402-3402/com.strongapps.frettrainer.android E/AndroidRuntime: FATAL EXCEPTION: main Process: com.strongapps.frettrainer.android, PID: 3402 java.lang.ClassCastException: s == null at com.securepreferences.SecurePreferences.getInt(SecurePreferences.java:389)

    Crashes in Android API 28 when trying to get a pref.

    opened by bitwalrus0 22
  • Using PBKDF2WithHmacSHA1 with 10k iterations and 48B output is too slow

    Using PBKDF2WithHmacSHA1 with 10k iterations and 48B output is too slow

    I'd very much like to use this library, but the initialization of the key takes 3 seconds on my Nexus 5. Since this is done in Application's onCreate (because I need the settings there), it's not usable.

    I understand that you're trying to make it as easy to use and as secure as possible, but would you consider allowing users of the library to provide their own key? Since the encryption is really more of an obfuscation (anyone can decompile the app and generate the same key), it wouldn't be a problem for me to have less security, but 100x faster startup time :)

    Also here's some discussion about the slowness: http://stackoverflow.com/questions/24652602/pbkdf2withhmacsha1-key-generation-takes-too-long-on-android

    enhancement 
    opened by cermakcz 13
  • SecureException in AesCbcWithIntegrity:installLinuxPRNGSecureRandom

    SecureException in AesCbcWithIntegrity:installLinuxPRNGSecureRandom

    Hi, last release of library crash on HUAWEI G630 U10 with Android 4.3.

    Caused by java.lang.SecurityException com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.installLinuxPRNGSecureRandom (AesCbcWithIntegrity.java:764) com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.apply (AesCbcWithIntegrity.java:684) com.tozny.crypto.android.AesCbcWithIntegrity.fixPrng (AesCbcWithIntegrity.java:347) com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword (AesCbcWithIntegrity.java:184) com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword (AesCbcWithIntegrity.java:234) com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword (AesCbcWithIntegrity.java:219) com.securepreferences.SecurePreferences. (SecurePreferences.java:145) com.securepreferences.SecurePreferences. (SecurePreferences.java:92)

    bug 
    opened by smred 10
  • Updating to 0.1.4 from 0.1.3 return null

    Updating to 0.1.4 from 0.1.3 return null

    I have updated the library to 0.1.4 and now, when I access to any secure preference it returns null and the app closes with a NullException.

    Is there something that I need to do after the update? Thanks!

    opened by javiersantos 9
  • Thread-safe for secure shared preferences

    Thread-safe for secure shared preferences

    The default shared preferences that comes with Android accept a flag called MODE_MULTI_PROCESS which makes the shared preferences thread-safe.

    Here is the quote to the official documentation:

    SharedPreference loading flag: when set, the file on disk will be checked for modification even if the shared preferences instance is already loaded in this process. This behaviour is sometimes desired in cases where the application has multiple processes, all writing to the same SharedPreferences file. Generally there are better forms of communication between processes, though.

    This was the legacy (but undocumented) behaviour in and before Gingerbread (Android 2.3) and this flag is implied when targetting such releases. For applications targetting SDK versions greater than Android 2.3, this flag must be explicitly set if desired.

    http://developer.android.com/reference/android/content/Context.html#MODE_MULTI_PROCESS

    opened by jiahaoliuliu 7
  • Use secure-preferences with Robolectric

    Use secure-preferences with Robolectric

    I am using secure-preferences to encrypt my local preferences. However, when using Robolectric to run unit tests, the preferences are not correctly filled in, and when trying to check if the key is contained in the file, it is always empty.

    My app code for the shared prefs:

    public class AppSharedPrefs {
        private ApplicationSharedPreferences(Context context) {
            sSharedPreferences = new SecurePreferences(context, context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE));
            sEditor = sSharedPreferences.edit();
            mContext = context;
    
            clearSharedPreferences();
    
        }
    
        public static ApplicationSharedPreferences getInstance(Context context) {
            if (instance == null) {
                instance = new ApplicationSharedPreferences(context);
            }
            return instance;
        }
    
        ... then all getter and setter ...
    }
    

    Then, my test code:

    @RunWith(TestRunner.class)
    public class CustomerAPITest extends GlobalTestCase {
    
        @Test
        public void handleActionTest() throws JSONException {
            final String VALUE = "1";
    
            AppSharedPreferences asp = AppSharedPreferences.getInstance(getTestContext());
            asp.setMyValue(VALUE);
    
            new CustomerAPI().handleAction();
            ....
        }
    }
    

    and my function in "handleAction()" will read VALUE, with:

    AppSharedPreferences asp = AppSharedPreferences.getInstance(context);
    asp.getMyValue(VALUE); // always null
    

    but is always null, shared preferences always empty. If I remove SecurePreferences and use standard Android prefs, everything works.

    Any clue how to solve this and if it is a problem of the library?

    opened by ntarocco 7
  • Add custom ProGuard/DexGuard config

    Add custom ProGuard/DexGuard config

    08-02 05:00:41.356 1533-1533/erparchitector.findwork.app.android E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.SecurityException: new SecureRandom() backed by wrong Provider: class com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes$LinuxPRNGSecureRandomProvider at com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.installLinuxPRNGSecureRandom(Unknown Source) at com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes.apply(Unknown Source) at com.tozny.crypto.android.AesCbcWithIntegrity.fixPrng(Unknown Source) at com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword(Unknown Source) at com.tozny.crypto.android.AesCbcWithIntegrity.generateKeyFromPassword(Unknown Source) at com.securepreferences.SecurePreferences.generateAesKeyName(Unknown Source) at com.securepreferences.SecurePreferences.(Unknown Source) at com.securepreferences.SecurePreferences.(Unknown Source) at com.securepreferences.SecurePreferences.(Unknown Source) at erparchitector.findwork.app.android.utils.Preferences.(Unknown Source) at erparchitector.findwork.app.android.network.Session.getInstance(Unknown Source) at erparchitector.findwork.app.android.App.getSession(Unknown Source) at erparchitector.findwork.app.android.gui.ProfileContainer.onCreate(Unknown Source) at android.support.v4.app.Fragment.performCreate(Unknown Source) at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source) at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source) at android.support.v4.app.BackStackRecord.run(Unknown Source) at android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source) at android.support.v4.app.FragmentManagerImpl$1.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)

    After proguard obfuscation :(

    opened by XandrMaster 6
  • Slows down my app

    Slows down my app

    Hello, ever since I upgraded to 0.0.1 from 0.0.4, my app has experienced tremendous slowdown. I mean like 10x slower! Any ideas what the issue could be here?

    Thanks, Igor

    opened by IgorGanapolsky 6
  • Question about license and using strong encryption outside of USA

    Question about license and using strong encryption outside of USA

    I am working on a Android application that i want to release to be available for customers from both USA and Romania. Does this library require a special license for using strong encryption? The reason why i ask this is because some other libraries like SQLCIpher for Android require special license for this ( according to this blog http://www.informit.com/articles/article.aspx?p=2268753&seqNum=3 )

    I was wondering if this is the case for this too. Please let me know. Thank you very much.

    opened by bogdanRada 5
  • Cannot instantiate SecurePrefs in testing

    Cannot instantiate SecurePrefs in testing

    Hi I am trying to write unit tests, one of which requires an instance of SecurePreferences. So I am passing a context like this: mContext = Mockito.mock(Context.class); securePreferences = new SecurePreferences(mContext);

    However, the context isn't mocked, and as a result I cannot use SecurePrefs in testing. Do you have any ideas about this?

    opened by IgorGanapolsky 5
  • Could not find com.scottyab:aes-crypto:0.0.2-SNAPSHOT

    Could not find com.scottyab:aes-crypto:0.0.2-SNAPSHOT

    Hi Scott,

    I was using your library with this configuration in Graddle.

    compile 'com.scottyab:aes-crypto:0.0.2-SNAPSHOT' compile('com.scottyab:secure-preferences-lib:0.1.0') { provided 'com.scottyab:aes-crypto:0.0.2-SNAPSHOT' }

    It was working fine until last week. I got an error that aes-crypto:002-SNAPSHOT cannot be found.

    Could you please check this.

    Kind regards,

    G

    opened by gabrielacosta 5
  • DeterministicAeadFactory.java line 13

    DeterministicAeadFactory.java line 13

    Fatal Exception: java.lang.SecurityException: Could not decrypt key. decryption failed at b.r.a.a.a(EncryptedSharedPreferences.java:22) at b.r.a.a.getAll(EncryptedSharedPreferences.java:4) at b.r.a.a$b.commit(EncryptedSharedPreferences.java:2) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6816) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1565) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1453)

    opened by shuaib29 0
  • Value can't be saved when put value after clear() and kill app in background.

    Value can't be saved when put value after clear() and kill app in background.

    Demo project - MainActivity: @DebugLog public void onGetButtonClick(View v) { final String value = getSharedPref().getString(MainActivity.KEY, null); toast(MainActivity.KEY + "'s, value= " + value); } @DebugLog public void onSetButtonClick(View v) { getSharedPref().edit().clear().commit();// Add this line getSharedPref().edit().putString(MainActivity.KEY, MainActivity.VALUE) .commit(); toast(MainActivity.KEY + " with enc value:" + MainActivity.VALUE + ". Saved"); } Then Kill app and relaunch, Click 'GET FOO' value =null. value should be 'Bar'.

    opened by IBeiBei 1
  • Android Canary 3.6 not building

    Android Canary 3.6 not building

    After thinking what is the root cause for a gradle build to fail. I suddenly remember your user name scottyab as I look to the error log and I believe that this is related to some of your repo.

    ERROR: Unable to resolve dependency for ':app@debug/compileClasspath': Failed to transform artifact 'aes-crypto.aar (com.scottyab:aes-crypto:0.0.5)' to match attributes {artifactType=jar}.

    opened by ArcherEmiya05 3
  • Security alert on our production app on google play console

    Security alert on our production app on google play console

    Hi,

    We are seeing a warning on our production app on google play console. The warning states:

    Security alert Your app contains unsafe cryptographic encryption patterns. Please see this Google Help Center article for details. Vulnerable classes: com.xxx.xxx.android.AesCbcWithIntegrity Affects APK version 10819.

    The article the warning is referring to https://support.google.com/faqs/answer/9450925

    Remediation for Unsafe Cryptographic Encryption - Google HelpThis information is intended for developers with app(s) that contain unsafe cryptographic encryption patterns. That is, a ciphertext is generated with a statically computed secret key, salt, or initiasupport.google.com

    Can someone help me to resolve this Security alert warning?

    opened by ashishdimi09 0
  • After updating to Android Q, i am not able to retrieve the data from the Secure preferences?

    After updating to Android Q, i am not able to retrieve the data from the Secure preferences?

    I upgraded my device to Android Q and now I am not able to retrieve the data stored in the SecurePreferences. Android Q release mode is around the corner and now it will be a disaster for my users if they are not able to see their data which is empty.

    Please tell me if there is any way to tackle this bug.

    opened by i-m-aman 10
Releases(v0.1.0)
  • v0.1.0(Apr 12, 2015)

    This release is a major refactor of the guts of secure prefs, which is Not backwards compatible with 0.4.0 and older versions yet!. So if you have an existing app using this don't upgrade. I'll be looking to add migration into a later release.

    • uses a new and stronger Crypto library under the hood
    • includes PRNG fixes that effects JellyBean devices as per google dev blog article
    • supports password based key generation so the key is not persisted
    • change password supported
    • updated sample app
    • removed test project and added tests as part of main project
    • refactored library project to standard gradle structure
    • published to maven central/added github release
    Source code(tar.gz)
    Source code(zip)
    secure-prefs-library-release-v0.1.0.aar(16.65 KB)
  • 0.4.0(Mar 27, 2015)

    0.0.4

    • Gradle support thanks @yelinaung
    • Fix for OnPreferenceChanged listener @richardleggett

    0.0.3

    • Added test Project
    • Updated sample ready for playstore upload

    0.0.2

    • Added methods to get/set strings un-encrypted
    • Added backup PBKDF function in case PBKDF2WithHmacSHA1 not supported
    • Refactored code to make it easier to change the AES mode and PBKDF function.
    • Increased iterations of PBKDF from 1000 to 2000.

    0.0.1

    • Initial import to github I've modified the project structure.
    • Included the Android base64 class so library can be used by Android 2.1+.
    • Enhanced the sample project dumps current prefs to illustrate the fact they are stored encrypted and Base64 encoded.
    Source code(tar.gz)
    Source code(zip)
    secure-preferences-lib-0.0.4.aar(16.11 KB)
Owner
Scott Alexander-Bown
Android Developer (remote), author, speaker, father and scruffy looking nerf herder. Love coffee, Belgian beer and running. Founder @swmobilegroup
Scott Alexander-Bown
Aplicación Android para comprender como funciona el listado y las shared preferences

READ.ME Este proyecto tiene como finalidad explicar como se debe utilizar un RecyclerView con una vista bindeada a este. En el proyecto se puede ver c

Carlos Muñoz Bustamante 4 Apr 12, 2022
Reactor is key value database and is a great alternative to Shared Preferences.

Reactor Reactor is a fast and secure key-value library for Android, and has an embedded database based on the JSON structure and is a great alternativ

mr amir abbas 37 Oct 30, 2022
Expirable Disk Lru Cache is a secure(with encryption) wrapper for [DiskLruCache](https://github.com/JakeWharton/DiskLruCache) that allows expiring of key/value pairs by specifying evictionTimeSpan. It has very simple API.

ExpirableDiskLruCache ExpirableDiskLruCache is a wrapper for DiskLruCache that allows expiring of key/value pairs by specifying evictionTimeSpan. It h

Vijay Rawat 24 Oct 3, 2022
Wrapper around the android Camera class that simplifies its usage

EasyCamera Wrapper around the android Camera class that simplifies its usage (read more about the process) Usage: // the surface where the preview wil

Bozhidar Bozhanov 641 Dec 29, 2022
Preference wrappers for primitive types for Android

Typed Preferences This library for Android provides classes which allow to store and retrieve settings from the preferences. There is an individual cl

Tobias Preuss 189 Nov 25, 2022
Simple Mobile Tools 172 Dec 26, 2022
App to simulate making lemonada juice in form of attractive application

Project: Lemonade App - Starter Code Starter code for the first independent project for Android Basics in Kotlin Introduction This is the starter code

null 0 Oct 28, 2021
🎁 Android Intent & Bundle extensions that insert and retrieve values elegantly.

?? Android Intent & Bundle extensions that insert and retrieve values elegantly.

Jaewoong Eum 233 Dec 13, 2022
Preferences data store example

DataStore Example this example shows how you can use data store to store data in key value pairs and get rid of shared preferences Medium Article: htt

Kashif Mehmood 24 Dec 15, 2022
⚙ A beautiful and extensible API for bulding preferences screen

Material Preferences ?? Installation Add this in app's build.gradle file: implementation 'com.imangazaliev.material-prefs:core:<version>' implementati

Mahach Imangazaliev 59 Jul 26, 2022
Tool to look for several security related Android application vulnerabilities

Quick Android Review Kit This tool is designed to look for several security related Android application vulnerabilities, either in source code or pack

LinkedIn 2.9k Jan 2, 2023
Small utility used to add Homewizard Energy Socket tiles to Android Quick Settings

TileWizard [Alpha! Unstable!] Settings Result Functionality: Add up to 5 Wi-Fi Energy Sockets to Android Quick Settings. What do you need: Android dev

Niels Masdorp 2 Oct 19, 2021
✔️ Secure, simple key-value storage for Android

Hawk 2.0 Secure, simple key-value storage for android Important Note This version has no backward compatibility with Hawk 1+ versions. If you still wa

Orhan Obut 3.9k Dec 20, 2022
Android Secure SharedPreferences Using Facebook Conceal Encryption

SharedChamber Android Project : SharedChamber on top of SharedPreferences using Facebook Conceal Description Conceal provides a set of Java APIs to pe

Hafiq 95 Nov 25, 2022
Utilities I wish Android had but doesn't

wishlist Library of helpers and utilities that I wish were included in the Android SDK but aren't. If you think something in this library is already h

Kevin Sawicki 386 Nov 21, 2022
Same as the Outlined text fields presented on the Material Design page but with some dynamic changes. 📝 🎉

README SSCustomEditTextOutlineBorder Getting Started SSCustomEditTextOutLineBorder is a small kotlin library for android to support outlined (stroked)

Simform Solutions 194 Dec 30, 2022
ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions

ModernStorage ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions by apps dev

Google 1.1k Dec 30, 2022
Very easy to use wrapper library for Android SharePreferences

Treasure English document Treasure是一个Android平台上基于SharePreferences的偏好存储库,只需要定义接口,无需编写实现,默认支持Serializable和Parcelable。运行时0反射,不仅使用方便而且性能和原生写法几乎无差别。 使用方法 1

星一 507 Nov 12, 2022
🪁 Android Resources Wrapper Library

Kite Android Resource Wrapper Library. TLDR Fed up with typing ContextCompat, resources and context all over your apps to access your resources? Say n

Andrea Cioccarelli 132 Dec 9, 2022