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.randomBytesfunction provided by thecryptomodule; - Browser: if SubtleCrypto is available
window.crypto.getRandomValuesis 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-valuesmodule 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.generateKeyPairfunction provided by thecryptomodule; - Browser: if SubtleCrypto is available
window.crypto.subtle.generateKeyis 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-nativemodule 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
ivof 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_arrayin RFC 6234): the concatenation ofivandcipherText; - key (
keyin RFC 6234):authenticationKey; - result:
hmac;
- algorithm:
- return:
cipheredMessagewhich 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_arrayin RFC 6234): the concatenation ofivandcipherText; - key (
keyin RFC 6234):authenticationKey; - result:
hmac;
- algorithm:
- comparison of
hmacwithhmac2, 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.createCipherivfunction for AES andcrypto.createHmacfor HMAC provided by thecryptomodule; - Browser: if SubtleCrypto is available,
window.crypto.subtle.encryptis used for AES andwindow.crypto.subtle.signis 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) onclearTextto givecrc32of length 32 bits; - encryption:
RSAES-OAEPalgorithm (see RFC 8017 §7.1.1) with the following parameters:SHA1as the hash functionMGF1-SHA1(see RFC 8017 §B.2.1) as the mask generation function- the
Llabel left empty
- argument (noted
Min RFC 8017 §7.1.1): concatenation ofcrc32andcleartext - 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-OAEPalgorithm (see RFC 8017 §7.1.2) with the following parameters:SHA1as the hash function;MGF1-SHA1(see RFC 8017 §B.2.1) as mask generation function;- the
Llabel left empty;
- argument (noted
Cin RFC 8017 §7.1.2): concatenation ofcrc32andcleartext; - key used (noted
Kin RFC 8017 §7.1.2): private key of the recipient; - result
decipheredMessage;
- decompose
decipheredMessageintocrc32andclearText; - compute a checksum of type
CRC32(see POSIX.1-2017 §chksum) onclearTextto givecrc32-2of length 32 bits; - compare
crc32andcrc32-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-PSSalgorithm (see RFC 8017 §8.1.1), using in the first step theEMSA-PSSencoding (see RFC 8017 §9.1.1) with the following parameters:SHA256as the hash function;- MGF1
(see [RFC 8017 §B.2.1](https://tools.ietf.org/html/rfc8017)) withSHA256` 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
Min RFC 8017 §8.1.1):textToSign; - key used (noted
Kin 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-PSSalgorithm (see RFC 8017 §8.1.1), using in the first step theEMSA-PSSencoding (see RFC 8017 §9.1.1) with the following parameters:SHA256as the hash function;MGF1(see RFC 8017 §B.2.1) withSHA256as 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
Min RFC 8017 §8.1.2):textToSign; - signature (noted
Sin 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
signatureIsValidindicating 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.signandcrypto.verifyprovided by thecryptomodule; - Browser: if SubtleCrypto is available,
window.crypto.subtle.encrypt,window.crypto.subtle.decrypt,window.crypto.subtle.signandwindow.crypto.subtle.verifyare 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:
passphraseandsaltgiven; - result:
key;
- algorithm:
- return:
key.
Implementation
The implementation used depends on the target environment;
- Node.js: the function
crypto.scryptprovided by thecryptomodule is used; - Browser: the module
scrypt-jsis used. - React-native: the module
@seald-io/react-native-scryptis used, which itself uses libscrypt.