Skip to content

Instantly share code, notes, and snippets.


Daniel Ochoa shafty023

View GitHub Profile
* Copyright (c) 2016 AirWatch, LLC. All rights reserved.
* This product is protected by copyright and intellectual property laws in
* the United States and other countries as well as by international treaties.
* AirWatch products may be covered by one or more patents listed at
package com.boxer.sdk;
import android.content.Context;
shafty023 / RawKeyGenerator.kt
Created Jun 9, 2020
Generates a random 32 byte key
View RawKeyGenerator.kt
* Generates a random 32 byte key.
* @return a byte array containing random values
fun generateRandomKey(): ByteArray =
ByteArray(32).apply {
} else {
shafty023 / ByteArrayToHex.kt
Created Jun 9, 2020
Convert a ByteArray to Hex encoded String
View ByteArrayToHex.kt
private val HEX_CHARS = "0123456789ABCDEF".toCharArray()
* Extension function that converts a ByteArray to a hex encoded String
fun ByteArray.toHex(): String {
val result = StringBuilder()
forEach {
val octet = it.toInt()
val firstIndex = (octet and 0xF0).ushr(4)
shafty023 / CreateNewKey.kt
Created Jun 9, 2020
Wrapper function to create a new key
View CreateNewKey.kt
private lateinit var rawByteKey: ByteArray
private lateinit var dbCharKey: CharArray
* Generates a new database key.
fun createNewKey() {
// This is the raw key that we'll be encrypting + storing
rawByteKey = generateRandomKey()
// This is the key that will be used by Room
shafty023 / Storable.kt
Created Jun 9, 2020
Container for everything needed to decrypt db
View Storable.kt
* Container for everything needed for decrypting the database.
* @param iv initialization vector
* @param key encrypted database key
* @param salt cryptographic salt
data class Storable(val iv: String, val key: String, val salt: String)
shafty023 / save_to_prefs.kt
Created Jun 9, 2020
Persist the db key to storage
View save_to_prefs.kt
* Save the storable instance to preferences.
* @param storable a storable instance
fun saveToPrefs(context: Context, storable: Storable) {
val serialized = Gson().toJson(storable)
val prefs = context.getSharedPreferences("database",
prefs.edit().putString("key", serialized).apply()
shafty023 / get_raw_byte_key.kt
Created Jun 9, 2020
Decrypts the Storable instance using a passcode
View get_raw_byte_key.kt
* Decrypts the [Storable] instance using the [passcode].
* @pararm passcode the user's passcode
* @param storable the storable instance previously saved with [saveToPrefs]
* @return the raw byte key previously generated with [generateRandomKey]
fun getRawByteKey(passcode: CharArray, storable: Storable): ByteArray {
val aesWrappedKey = Base64.decode(storable.key, Base64.DEFAULT)
val iv = Base64.decode(storable.iv, Base64.DEFAULT)
View get_char_key.kt
* Returns the database key suitable for using with Room.
* @param passcode the user's passcode
* @param context the caller's context
fun getCharKey(passcode: CharArray, context: Context): CharArray {
if (dbCharKey == null) {
initKey(passcode, context)
shafty023 / encrypt_and_store_key.kt
Last active Jun 9, 2020
Encrypt the key and store it
View encrypt_and_store_key.kt
fun persistRawKey(userPasscode: CharArray) {
val storable = toStorable(rawByteKey, userPasscode)
// Implementation explained in next step
* Returns a [Storable] instance with the db key encrypted using PBE.
* @param rawDbKey the raw database key
View encrypted_room_db.kt
abstract class EncryptedDatabase : RoomDatabase() {
companion object {
fun getInstance(passcode: CharArray, context: Context):
EncryptedDatabase = buildDatabase(passcode, context)
private fun buildDatabase(
passcode: CharArray,
context: Context
): EncryptedDatabase {
// DatabaseKeyMgr is a singleton that all of the above code is wrapped into.
You can’t perform that action at this time.