Secure serializing objects using sealedobject class | Concise Software

Secure serializing objects using sealedobject class

In this article we’ll take the approach of serializing and deserializing objects, with symmetric cryptographic key usage. Most articles describing that topic, require from developer to store inside application additional data, which are required to decrypt data. I’m going to show you how we can achieve the same goal with easier approach, by using SealedObject class.

Generating key

Data encryption is taking place in few steps. Firstly, we are going to generate cryptographic key using AES standard. It’ll give us the possibility to easily encrypt large amount of data.

static final String ENCRYPTION_STANDARD = "AES";
static final String KEY_PROVIDER = "AndroidKeyStore";
static final String KEY_ALIAS = "key";

KeyGenerator keyGenerator = KeyGenerator.getInstance(ENCRYPTION_STANDARD, KEY_PROVIDER);
KeyGenParameterSpec specs = new KeyGenParameterSpec.Builder(KEY_ALIAS,
SecretKey key = keyGenerator.generateKey();

We have passed a few parameters here:

  • KEY_PROVIDER – provider instance in which Android should look up for AES implementation
  • KEY_ALIAS – alias under which key could be found later we gave our key a purpose to encrypt & decrypt data
  • BLOCK_MODE_CBC – cryptographic block mode with which our key can be used
  • ENCRYPTION_PADDING_PKCS7 – default padding scheme with which our key can be used

On Android 6.0 and above our newly generated key would become automatically saved in provided Keystore for further use. Android Keystore System gives the possibility to store cryptographic keys in a secure way, without any chance of exporting them from the device.

Cipher initialization

Our next step is going to initialize Cipher object, which will encrypt our data. We’ll create it by passing transformation parameters used when generating our AES key. Then, we’ll initialize it with our key in Encryption mode.

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);

Up to that point, everything is pretty similar to what you can find in other articles, but here comes the difference. In code above we intentionally omitted passing Initialization Vector parameter, which is required when using CBC block mode. When encrypting data using CBC mode, each data block is being encrypted with block from previous itera