# Cryptographic mechanisms

Here you will find a brief definition of the cryptographic mechanisms used by Seald.

Their implementation used in Seald is `SSCrypto`

.

## Randomness generation

Depending on the target environment, different random generators are used:

- Node.js: the
`crypto.randomBytes`

function provided by the`crypto`

module; - Browser: if SubtleCrypto is available
`window.crypto.getRandomValues`

is used. For very old browsers (Chrome <37, Edge<12, IE<11, Firefox<34, Opera<24, Safari<7) a pure JavaScript implementation is provided by node-forge, this is a modified version of Fortuna whose*seed*is derived from the date and browser usage parameters (mouse movements, etc.) - React-native: the
`react-native-get-random-values`

module provides a secure seed for the Fortuna-based PRNG of node-forge.

## Asymmetric key pair generator

The keys used are of type RSA (see RFC 8017).

Depending on the target environment, different asymmetric key pair generators are used:

- Node.js: the
`crypto.generateKeyPair`

function provided by the`crypto`

module; - Browser: if SubtleCrypto is available
`window.crypto.subtle.generateKey`

is used. For very old browsers (Chrome <37, Edge<79, IE, Firefox<34, Opera<24, Safari<7) a pure JavaScript implementation is provided by node-forge, this is a version of`PRIMEINC`

. - React-native: the
`react-native-rsa-native`

module which uses the SpongyCastle generator in version 1.56 on Android and that of the standard library on iOS.

## Symmetric encryption

To encrypt symmetrically, two algorithms are used to ensure both confidentiality and integrity: an encryption scheme that provides confidentiality only, and a MAC to ensure integrity.

### Sizing

Two symmetric keys are used

- a 256-bit encryption key noted
`encryptionKey`

; - a 256-bit key for the MAC, noted
`authenticationKey`

.

Their concatenation in this order is noted `messageKey`

.

### Lifetime

Keys are used for an indefinite period of time for the data they protect.

### Encryption

Symmetric encryption of `clearText`

with a `messageKey`

(concatenation of `encryptionKey`

and `authenticationKey`

) to obtain `cipheredMessage`

is done as follows

- generation of a random initialization vector denoted
`iv`

of 128 bits; - encryption:
- algorithm:
`AES-256-CBC`

(see FIPS 197 and NIST Special Publication 800-38A §6.2); - initialization vector:
`iv`

; - key:
`encryptionKey`

; - argument:
`clearText`

; - result:
`cipherText`

;

- algorithm:
- MAC:
- algorithm:
`HMAC-SHA-256`

(see RFC 6234 §8.3); - argument (
`message_array`

in RFC 6234): the concatenation of`iv`

and`cipherText`

; - key (
`key`

in RFC 6234):`authenticationKey`

; - result:
`hmac`

;

- algorithm:
- return:
`cipheredMessage`

which is the concatenation of`iv`

,`cipherText`

, and`hmac`

.

### Decryption

Symmetric decryption of `cipheredMessage`

(concatenation of `iv`

, `cipherText`

, and `hmac`

) with a `messageKey`

(concatenation of `encryptionKey`

and `authenticationKey`

) to obtain `clearText`

is done as follows:

- MAC:
- algorithm:
`HMAC-SHA-256`

(see RFC 6234 §8.3); - argument (
`message_array`

in RFC 6234): the concatenation of`iv`

and`cipherText`

; - key (
`key`

in RFC 6234):`authenticationKey`

; - result:
`hmac`

;

- algorithm:
- comparison of
`hmac`

with`hmac2`

, if equal continue; - decryption:
- algorithm:
`AES-256-CBC`

(see FIPS 197 and NIST Special Publication 800-38A §6.2); - initialization vector:
`iv`

; - argument:
`cipherText`

; - key:
`encryptionKey`

; - result:
`clearText`

;

- algorithm:
- return
`clearText`

.

### Envelope

When using the SDK, `cipheredMessage`

is put in an envelope format:

### Implementation

The implementation used depends on the target environment;

- Node.js: the
`crypto.createCipheriv`

function for AES and`crypto.createHmac`

for HMAC provided by the`crypto`

module; - Browser: if SubtleCrypto is available,
`window.crypto.subtle.encrypt`

is used for AES and`window.crypto.subtle.sign`

is used for HMAC. For very old browsers (Chrome <37, Edge<79, IE, Firefox<34, Opera<24, Safari<7) a pure JavaScript implementation is provided by node-forge. - React-native: a pure JavaScript implementation is provided by node-forge.

## Asymmetric cryptography

The keys used are of type RSA (see RFC 8017).

One pair of keys is reserved for encryption operations, another for signature operations.

### Sizing

The keys are generated with a modulus `n`

of 4096 bits and a public exponent `e`

of 65537.

### Lifetime

These keys are generated for a duration not exceeding 157680000 seconds (5 years), with a default lifetime of 94608000 seconds (3 years).

### Asymmetric encryption

The asymmetric encryption of a `clearText`

with a public key `(n,e)`

given to obtain `cipheredMessage`

is performed as follows

- computing a checksum of type
`CRC32`

(see POSIX.1-2017 §chksum) on`clearText`

to give`crc32`

of length 32 bits; - encryption:
`RSAES-OAEP`

algorithm (see RFC 8017 §7.1.1) with the following parameters:`SHA1`

as the hash function`MGF1-SHA1`

(see RFC 8017 §B.2.1) as the mask generation function- the
`L`

label left empty

- argument (noted
`M`

in RFC 8017 §7.1.1): concatenation of`crc32`

and`cleartext`

- key used (noted
`(n,e)`

in RFC 8017 §7.1.1): public key of the recipient - result `cipheredMessage

- return:
`cipheredMessage`

TIP

The use of `SHA-1`

as a hash function in `RSAES-OAEP`

is robust and compliant with RGS v2.0 (see §B1.2.2.2), even considering that collisions are possible. For more information, see What Hashes Make RSA-OAEP Secure?.

### Asymmetric decryption

Asymmetric decryption of a `cipheredMessage`

with a private key denoted `K`

given to obtain `clearText`

is performed as follows:

- decryption:
`RSAES-OAEP`

algorithm (see RFC 8017 §7.1.2) with the following parameters:`SHA1`

as the hash function;`MGF1-SHA1`

(see RFC 8017 §B.2.1) as mask generation function;- the
`L`

label left empty;

- argument (noted
`C`

in RFC 8017 §7.1.2): concatenation of`crc32`

and`cleartext`

; - key used (noted
`K`

in RFC 8017 §7.1.2): private key of the recipient; - result
`decipheredMessage`

;

- decompose
`decipheredMessage`

into`crc32`

and`clearText`

; - compute a checksum of type
`CRC32`

(see POSIX.1-2017 §chksum) on`clearText`

to give`crc32-2`

of length 32 bits; - compare
`crc32`

and`crc32-2`

, if equal continue; - return:
`clearText`

.

### Signature

The production of a `signature`

signature of a `textToSign`

using a private key denoted `K`

is performed as follows:

- signature:
`RSASSA-PSS`

algorithm (see RFC 8017 §8.1.1), using in the first step the`EMSA-PSS`

encoding (see RFC 8017 §9.1.1) with the following parameters:`SHA256`

as the hash function;- MGF1
`(see [RFC 8017 §B.2.1](https://tools.ietf.org/html/rfc8017)) with`

SHA256` as the hash function; `sLen`

: the maximum length worth 478 bytes given the chosen hash function and the length of the chosen key module;

- argument (noted
`M`

in RFC 8017 §8.1.1):`textToSign`

; - key used (noted
`K`

in RFC 8017 §8.1.1): Private key of the signer; - result:
`signature`

;

- return:
`signature`

.

### Signature verification

Verification of a `signature`

signature of a `textToSign`

using a public key denoted `(n,e)`

associated with the private key `K`

used to sign is performed as follows:

- signature verification:
`RSASSA-PSS`

algorithm (see RFC 8017 §8.1.1), using in the first step the`EMSA-PSS`

encoding (see RFC 8017 §9.1.1) with the following parameters:`SHA256`

as the hash function;`MGF1`

(see RFC 8017 §B.2.1) with`SHA256`

as the hash function;`sLen`

: the maximum length worth 478 bytes given the chosen hash function and the length chosen for the key module;

- arguments:
- message (noted
`M`

in RFC 8017 §8.1.2):`textToSign`

; - signature (noted
`S`

in RFC 8017 §8.1.2):`signature`

;

- message (noted
- key used (noted
`(n,e)`

in RFC 8017 §8.1.2): signer's public key; - result: boolean
`signatureIsValid`

indicating if the signature is valid for the message;

- return:
`signatureIsValid`

.

### Implementation

The implementation used depends on the target environment;

- Node.js: the functions
`crypto.privateDecrypt`

,`crypto.publicEncrypt`

,`crypto.sign`

and`crypto.verify`

provided by the`crypto`

module; - Browser: if SubtleCrypto is available,
`window.crypto.subtle.encrypt`

,`window.crypto.subtle.decrypt`

,`window.crypto.subtle.sign`

and`window.crypto.subtle.verify`

are used. For very old browsers (Chrome <37, Edge<79, IE, Firefox<34, Opera<24, Safari<7) a pure JavaScript implementation is provided by node-forge. - React-native: a pure JavaScript implementation is provided by node-forge.

## Key derivation

Deriving a key from a `passphrase`

and a `salt`

to obtain `key`

is done as follows

- derivation:
- algorithm:
`SCrypt`

, with the following parameters:`N`

: 16384;`r`

: 8;`p`

: 1;- output size: 64 bytes;

- arguments:
`passphrase`

and`salt`

given; - result:
`key`

;

- algorithm:
- return:
`key`

.

### Implementation

The implementation used depends on the target environment;

- Node.js: the function
`crypto.scrypt`

provided by the`crypto`

module is used; - Browser: the module
`scrypt-js`

is used. - React-native: the module
`@seald-io/react-native-scrypt`

is used, which itself uses libscrypt.