CryptoAPI

Stable Version 2.2.0 (O11)
Also available for 10, 9.0, Older
Published on 03 March 2019 by 
Ricardo Silva
Stable Version 2.2.0 (O11)
Also available for 10, 9.0, Older
Published on 03 March 2019 by 
Ricardo Silva
Created on 28 July 2013

CryptoAPI

Documentation

Why did I make this component?

Some of you may be asking why I made this component since the Enterprise Manager already provides a Crypto library.

There are a couple of problems I found with the EnterpriseManager Crypto extension:

1) the encryption scheme used is relatively weak by today's standards. It is not Chosen Plaintext secure, which basically means it's possible to tell when ciphertexts relate to the same plaintext (with the same key), which leaks some information.

2) It uses custom implementations of some of the cryptographic primitives, which is generally a bad practice.

3) It does not use an authenticated encryption schema which means that your data may be tampered without you realizing it.

For reference, the EM Crypto extension uses AES in CBC mode with PKCS7 padding with fixed Initialization Vector. The key derivation for EM Crypto, for interoperability reasons, has custom code in the Java version.


Algorithms used

In this extension, I have two encryption schemas. One for randomized encryption and another for deterministic encryption. Both of them provide authenticated encryption, meaning they'll let you know if the ciphertext has been tampered with.

Randomized encryption schema (Encrypt/Decrypt Actions): AES with 256 bit key in CBC mode with PKCS7 padding and randomized Initialization Vector + HMACSHA256 for integrity. I use the same key for confidentiality and integrity. Ciphertext is Base64Encode(iv || E(iv,k,plaintext) || mac(k, iv || E(iv,k,plaintext))

Deterministic encryption schema (Det_Encrypt/Det_Decrypt Actions): AES with 256 bit key in CBC mode with PKCS7 padding and Synthetic Initialization vector taken from the first 16 bytes of the HMACSHA256 mac of the plaintext. I use the same key for confidentiality and integrity. Ciphertext is Base64Encode( MSB(128, mac(k, plaintext)) || E(iv, k, plaintext) ) where MSB(b, v) stands for the b most significant bits (left-most) of v.

Asymmetric encryption schema uses RSA with OAEP padding with the common MFG1 and SHA1 functions as parameters.

Integrity schema (ComputeMac action): HMACSHA256 with 256-bit key.

Key derivation (DeriveKey action): RFC 2898 PBKDF2 with fixed 128-byte salt using HMACSha1 as the underlying mac algorithm with 37649 iterations.

All crypto implementations are taken from either .NET framework crypto library or from bouncy castle (in Java).

Data (strings) are utf-8 encoded prior to encryption and utf-8 decoded upon decryption. 


Bulk processing

If you want to process a lot of data with the same key, you can use the K* version of the actions to avoid deriving the key for each encryption/mac. This is also one of the reasons why key derivation uses a fixed salt. If the salt was unique per encryption you couldn't bulk process anything since you couldn't pre-process the key.


What should I use?

If you're looking to just encrypt some data, you should use the Encrypt family of actions.

If you want to add some encrypted field as searchable, you can use the Det_Encrypt family of actions. In order to maintain security, you should make sure that you do not use the same key to encrypt the same data twice on the database (the attribute holding the encrypted data should have a unique constraint)

Support Options
This component is not supported by OutSystems. You may use the discussion forums to leave suggestions or obtain best-effort support from the community, including from Ricardo Silva who created this component.
Dependencies
CryptoAPI has no dependencies.