Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
at.favre.lib:armadillo
Advanced tools
A shared preference implementation for confidential data. Per default uses AES-GCM, BCrypt and HKDF as cryptographic primitives. Uses the concept of Fingerprinting combined with optional user provided passwords.
A shared preference implementation for secret data providing confidentiality, integrity and authenticity . Per default uses AES-GCM, BCrypt and HKDF as cryptographic primitives.
Important Notice: If you migrate to v0.6.0 and use a user password and default key stretching function migration is needed due to a security issue. See migration guide in the changelog for v0.6.0
Add the following to your dependencies (add jcenter to your repositories if you haven't)
compile 'at.favre.lib:armadillo:x.y.z'
A very minimal example
SharedPreferences preferences = Armadillo.create(context, "myPrefs")
.encryptionFingerprint(context)
.build();
preferences.edit().putString("key1", "stringValue").commit();
String s = preferences.getString("key1", null);
The following example shows some of the configurations available to the developer:
String userId = ...
SharedPreferences preferences = Armadillo.create(context, "myCustomPreferences")
.password("mySuperSecretPassword".toCharArray()) //use user provided password
.securityProvider(Security.getProvider("BC")) //use bouncy-castle security provider
.keyStretchingFunction(new PBKDF2KeyStretcher()) //use PBKDF2 as user password kdf
.contentKeyDigest(Bytes.from(getAndroidId(context)).array()) //use custom content key digest salt
.secureRandom(new SecureRandom()) //provide your own secure random for salt/iv generation
.encryptionFingerprint(context, userId.getBytes(StandardCharsets.UTF_8)) //add the user id to fingerprint
.supportVerifyPassword(true) //enables optional password validation support `.isValidPassword()`
.enableKitKatSupport(true) //enable optional kitkat support
.enableDerivedPasswordCache(true) //enable caching for derived password making consecutive getters faster
.build();
A xml file named like f1a4e61ffb59c6e6a3d6ceae9a20cb5726aade06.xml
will
be created with the resulting data looking something like that after the
first put operation:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<!-- storage random salt -->
<string name="585d6f0f415682ace841fb50d5980d60ed23a2ef">riIPjrL2WRfoh8QJXu7fWk4GGeAKlQoJl9ofABHZKlc=</string>
<!-- 'key1':'stringValue' -->
<string name="152b866fd2d63899678c21f247bb6df0d2e38072">AAAAABD/8an1zfovjJB/2MFOT9ncAAAAJaf+Z9xgzwXzp1BqTsVMnRZxR/HfRcO8lEhyKpL17QmZ5amwAYQ=</string>
</map>
Unfortunately Android SDK 19 (KITKAT) does not fully support AES GCM mode. Therefore a backwards compatible implementation of AES using CBC with Encrypt-then-MAC can be used to support this library on older devices. This should provide the same security strength as the GCM version, however the support must be enabled manually:
SharedPreferences preferences = Armadillo.create(context, "myCustomPreferences")
.enableKitKatSupport(true)
...
.build();
In this mode, if on a KitKat device the backwards-compatible implementation is used, the default AES-GCM version otherwise. Upgrading to a newer OS version the content should still be decryptable, while newer content will then be encrypted with the AES-GCM version.
AndroidOpenSSL
provider which is fast (probably hardware accelerated for e.g. AES) and
heavily used by e.g. TLS implementation.A high entropy value not known to any system but the user is a good and strong base for a cryptographic key. Unfortunately user-based passwords are often weak (low-entropy). To mitigate that fact and help preventing easy brute-forcing key derivation functions with key stretching properties are used. These functions calculate pseudo-random data from it's source material which requires mandatory work.
The following implementations are available:
It is possible to provide any KDF implementation to the storage with providing
a custom KeyStretchingFunction
implementation.
Note, if you use key stretching put/get operations will get very slow (depeding on the work factor of course), so consider accessing the store in a background thread.
This store bases part of it's security on so called fingerprinting. That basically means, during runtime entropy from e.g. the device, system or other parts are used to create a cryptographic key with which the data is encrypted. It basically is encryption with a semi-secret key.
This has the following benefits:
This store has a default implementation of EncryptionFingerprint
which
can only use generic data. In detail the following properties are incorporated:
The security of this mechanism increases considerably if the user adds it's own data. Here are some suggestions:
The cryptographic key used to encrypt the data is composed of the following parts:
The concatenated key material will be derived and stretched to the desired length with HKDF derivation function.
The key is hashed with HKDF (which uses Hmac with Sha512 internally) expanded to a 20 byte hash which will be encoded with base16 (hex). The key generation is salted by the encryption fingerprint, so different shared preferences will generate different hashes for the same keys.
The diagram below illustrates the used data format. To disguise the format a little bit it will be obfuscated by a simple xor cipher.
The resulting data will be encoded with base64 and looks like this in the shared preferences xml:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="39e3e4f83dda81c44f8a9063196b28b3d5091fca">hwbchXlqDAQcig6q3UWxdbOb2wouDGGwjUGNIzREiy0=</string>
<string name="62ef41ac992322bdd669e96799c12a66a2cce111">AAAAABAAajtOaVCq5yqu1TPxgLu2AAAAqUTxgPcAM6lyNTGgy7ZAoCjqcCdtxT6T</string>
</map>
All tags and commits by me are signed with git with my private key:
GPG key ID: 4FDF85343912A3AB
Fingerprint: 2FB392FB05158589B767960C4FDF85343912A3AB
Assemble the lib with the following command
./gradlew :armadillo:assemble
The .aar
files can then be found in /armadillo/build/outputs/aar
folder
Copyright 2017 Patrick Favre-Bulle
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.
FAQs
A shared preference implementation for confidential data. Per default uses AES-GCM, BCrypt and HKDF as cryptographic primitives. Uses the concept of Fingerprinting combined with optional user provided passwords.
We found that at.favre.lib:armadillo demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.