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 thecrypto
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 thecrypto
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 ofPRIMEINC
. - 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 ofiv
andcipherText
; - key (
key
in RFC 6234):authenticationKey
; - result:
hmac
;
- algorithm:
- return:
cipheredMessage
which is the concatenation ofiv
,cipherText
, andhmac
.
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 ofiv
andcipherText
; - key (
key
in RFC 6234):authenticationKey
; - result:
hmac
;
- algorithm:
- comparison of
hmac
withhmac2
, 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 andcrypto.createHmac
for HMAC provided by thecrypto
module; - Browser: if SubtleCrypto is available,
window.crypto.subtle.encrypt
is used for AES andwindow.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) onclearText
to givecrc32
of length 32 bits; - encryption:
RSAES-OAEP
algorithm (see RFC 8017 §7.1.1) with the following parameters:SHA1
as the hash functionMGF1-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 ofcrc32
andcleartext
- 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 ofcrc32
andcleartext
; - key used (noted
K
in RFC 8017 §7.1.2): private key of the recipient; - result
decipheredMessage
;
- decompose
decipheredMessage
intocrc32
andclearText
; - compute a checksum of type
CRC32
(see POSIX.1-2017 §chksum) onclearText
to givecrc32-2
of length 32 bits; - compare
crc32
andcrc32-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 theEMSA-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 theEMSA-PSS
encoding (see RFC 8017 §9.1.1) with the following parameters:SHA256
as the hash function;MGF1
(see RFC 8017 §B.2.1) withSHA256
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
andcrypto.verify
provided by thecrypto
module; - Browser: if SubtleCrypto is available,
window.crypto.subtle.encrypt
,window.crypto.subtle.decrypt
,window.crypto.subtle.sign
andwindow.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
andsalt
given; - result:
key
;
- algorithm:
- return:
key
.
Implementation
The implementation used depends on the target environment;
- Node.js: the function
crypto.scrypt
provided by thecrypto
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.