Crypto

This document describes the Crypto library available in the JavaScript environment for app serivices.

Table of content

Object Crypto
Functions hash
hmac
cipher

Object Hash
Functions update
final

Object Hmac
Functions update
final

Object Cipher
Members iv
getIv
crypt
close

Examples Encrypting and signing a JS object

Crypto

hash

Creates a Hash object that can be used for the calculation of cryptographic hashes.

The objects allocates persistent memory in the JavaScript Runtime until the final function is called.

Parameters

string algorithmThe hash algorithm to be used. Supported values are "SHA224", "SHA256", "SHA384", "SHA512", "SHA1", "MD5", "MD4".

Return value

HashAn object that can be used for the hash calculation.
var digest = Crypto.hash("SHA256").update("data1").update("data2").final();
hmac

Creates a Hmac object that can be used for the calculation of a hash-based message authentication code.

The objects allocates persistent memory in the JavaScript Runtime until the final function is called.

Parameters

string algorithmThe hash algorithm to be used. Supported values are "SHA224", "SHA256", "SHA384", "SHA512", "SHA1", "MD5", "MD4".
string/Uint8Array keyThe password or key that shall be used for the calculation.

Return value

HmacAn object that can be used for the HMAC calculation.
var mac = Crypto.hmac("SHA256","password").update("data1").update("data2").final();
cipher

Creates a Cipher object that can be used for the encryption / decryption.

The objects allocates persistent memory in the JavaScript Runtime until close or crypt with last=true is called.

Note: Cryptography is non-trivial. It's easy to make small mistakes on application level that break security completely. Don't just use the library functions but make sure you have a good understanding how to use the specific algorithm and mode.

Parameters

string algorithmThe cryptographic algorithm to be used. Supported values are "AES", "RC4", "DES".
string modeThe mode of operation to be used.
Supported modes for "AES" are "ECB", "CTR", "CBC", "CTS", "CFB". null defaults to "ECB".
Supported modes for "DES" are "CBC".
Use null for "RC4".
string/Uint8Array key The key for encryption/decryption.
For "AES" a key of 16 bytes (AES-128), 24 bytes (AES-192) or 32 bytes (AES-256) is needed. The function accepts both hexstrings and binary keys given as a Uint8Array.
For "DES" a key of 8 bytes (64 bit) is needed. The function accepts both hexstrings and binary keys given as a Uint8Array.
For "RC4" a key of arbitrary length can be used. It can be specified as a string (password) or as a binary key given as a Uint8Array.
Important: Never reuse the same key for "RC4". As RC4 is a stream cipher, the key needs to be globally unique to maintain security.
Important: Never reuse the same key/iv combination for "AES" in "CTR" mode. As AES-CTR is a stream cipher, the key/iv combination needs to be globally unique to maintain security.
bool encrypt true for encryption (default).
false for decryption
Note: For stream ciphers like RC4 or AES-CTR there is no difference between encryption and decryption, so both values give the same result.

Return value

cipherAn object that can be used for performing the encryption or decryption.
var ciphertext = Crypto.cipher("RC4", null, "password").crypt("secretdata");
var decrypted = Crypto.cipher("RC4", null, "password").crypt(ciphertext);

Hash

update
Includes a chunk of data into the hash calculation.

Parameters

string/Uint8Array keyThe input data. The function accepts both strings and binary data as Uint8Array.

Return value

HashA reference to the object itself. Useful for method chaining.
final
Caluclates the hash value.

Parameters

bool binaryOptional, defaulting to false. Specifies if the function should return the hash value as a hexstring or as a binary Uint8Array.

Return value

string/Uint8ArrayThe calculated hash value as a hexstring or Uint8Array, depending on the binary parameter.

Remarks

Calling this function will delete the object and free all associated memory in the JavaScript Runtime.

var digestHexString = Crypto.hash("SHA256").update("data1").update("data2").final();
var digestBinary = Crypto.hash("SHA256").update("data1").update("data2").final(true);

Hmac

update
Includes a chunk of data into the HMAC calculation.

Parameters

string/Uint8Array keyThe input data. The function accepts both strings and binary data as Uint8Array.

Return value

HmacA reference to the object itself. Useful for method chaining.
final
Caluclates the HMAC value.

Parameters

bool binaryOptional, defaulting to false. Specifies if the function should return the hash value as a hexstring or as a binary Uint8Array.

Return value

string/Uint8ArrayThe calculated hash value as a hexstring or Uint8Array, depending on the binary parameter.

Remarks

Calling this function will delete the object and free all associated memory in the JavaScript Runtime.

var hacHexString = Crypto.hmac("SHA256","password").update("data1").update("data2").final();
var hmacBinary = Crypto.hmac("SHA256","password").update("data1").update("data2").final(true);

Cipher

iv

Sets an explicit initialization vector. If the function is never called, an IV consisting of null bytes is used.
The following modes of operation use an initialization vector: "CTR", "CFB", "CBC", "CTS".
"AES" uses an initialization vector of 16 bytes
"DES" uses an initialization vecrot of 8 bytes

Parameters

string/Uint8Array ivThe initialzation vector to be used from the next crypt operation. The function accepts both hexstrings and binary data as Uint8Array.

Return value

cipherA reference to the object itself. Useful for method chaining.
getIv

Returns the current IV.

Parameters

bool binaryOptional, defaulting to false. Specifies if the function should return a hexstring or a binary Uint8Array.

Return value

string/Uint8ArrayThe current IV value as a hexstring or Uint8Array, depending on the binary parameter.
crypt
Encrypts or decrypts a chunk of data.

Parameters

string/Uint8Array data The data to be encrypted/decrypted.
For encryption the functions accepts strings or binary data as Uint8Array.
For decryption the function accepts hexstrings or binary data as Uint8Array.
Depending on the algorithm and mode of operation there are restrictions on the data size that can be processed.
"RC4" allows arbitrary data sizes.
"AES" in "CTR" or "CTS" mode allow arbitary data sizes.
All other modes of "AES" expect multiples of 16 bytes
"DES" expects multiples of 8 bytes
bool binary Optional, defaulting to false.
If false, the function will return a hexstring for encryption and a string for decryption.
Otherwise the function will return binary data as a Uint8Array.
bool last Optional, defaulting to true.
If true, the Cipher object will be deleted after the operation, along with all associated data in the JavaScript Runtime.
if false, the object can be reused for encrypting / decrypting additional chunks of data.

Return value

string/Uint8ArrayThe encrypted/decrypted data a string/hexstring or Uint8Array, depending on the binary parameter.
var key = "73757065727375706572736563726574";
var iv = "00000000000000000000000000000000";
var plaintext = "This is the secret text to be encrypted";

// encryption using AES-128 in CTR mode
var ciphertext = Crypto.cipher("AES", "CTR", key, true).iv(iv).crypt(plaintext);

// decryption using AES-128 in CTR mode
var decrypted = Crypto.cipher("AES", "CTR", key, false).iv(iv).crypt(ciphertext);

// now decrypted contains the plain text again
close
Deletes the object and frees all associated data in the JavaScript Runtime. Can be used to dispose the object, as an alternative to calling close with last set to true.

Example: Encrypting and signing a JS object

Let's make up an example that brings everything together. For that let's create a function that does the following:
function encryptObject(obj, passphrase) {
    // serialize the object
    var plaintext = JSON.stringify(obj);
    // calculate HMAC
    var hmac = Crypto.hmac("SHA256", passphrase).update(plaintext).final();
    // create random 128-Bit IV
    var iv = Random.bytes(16);
    // create 256-Bit encryption key from passphrase by hashing it using SHA256
    var key = Crypto.hash("SHA256").update(passphrase).final();
    // encrypt
    var ciphertext = Crypto.cipher("AES", "CTR", key, true).iv(iv).crypt(plaintext);
    
    return {
        iv: iv,
        data: ciphertext,
        hmac: hmac
    };
}
Next, let's create the corresponding decryption function.
function decryptObject(obj, passphrase) {
    if (!obj || !obj.iv || !obj.data || !obj.hmac) return null;

    // create 256-Bit encryption key from passphrase by hashing it using SHA256
    var key = Crypto.hash("SHA256").update(passphrase).final();
    // decrypt
    var plaintext = Crypto.cipher("AES", "CTR", key, false).iv(obj.iv).crypt(obj.data);
    // calculate HMAC
    var hmac = Crypto.hmac("SHA256", passphrase).update(plaintext).final();

    // check if decryption was successfull
    if (hmac == obj.hmac) {
        return JSON.parse(plaintext);
    }
    
    return null;
}
We can test it with the following code.

var passphrase = "D4s 1s7 d4s H4us v0m N1c0l4us!!1";

var input = { text: "Hi, this is top secret. We should protect it.", x: 42 };
log("input:     " + JSON.stringify(input));

var encrypted = encryptObject(input, passphrase);
log("encrypted: " + JSON.stringify(encrypted));

var decrypted = decryptObject(encrypted, passphrase);
log("decrypted: " + JSON.stringify(decrypted));
In the log we can see an output like that:

JS: input:     {"text":"Hi, this is top secret. We should protect it.","x":42}
JS: encrypted: {"iv":"357bf81d63418a6fdedce56558667d29","data":"f0a454da39d7306770afc7ea781904b2d49b4adb9d4f1790898d28145503a8d2183e4c53ec4e696a95938ee1c25bf5d29b24851c45a31fc6e13842887b267c","hmac":"9502652073243900ae42a4b864b05d17c3ec18b0983e3aa9ae76099be5642bac"}
JS: decrypted: {"text":"Hi, this is top secret. We should protect it.","x":42}