Schemas: Encrypt

Encrypting field values ​​with AES in MerlinDB.

🪶 Firstly, AES (Advanced Encryption Standard) is a symmetric encryption algorithm used worldwide to protect data.

The encrypt property can encrypt any data, just provide a value and it is a 'secret key to decrypt'.


The encrypt property has 4 options, they are:

hash {("SHA-256"|"SHA-384"|"SHA-512")} - It is a function that transforms an input (or "message") into a fixed output;

- SHA-256: Generates a 256-bit hash (32 bytes).

- SHA-384: Generates a 384-bit hash (48 bytes).

- SHA-512: Generates a 512-bit hash (64 bytes).


salt {Number} - Is a random value added to the input of a hash function to ensure that the output (the hash) is unique, even if the original input (e.g. a password) is the same.

iterations {Number} - Refers to the number of times a hash function is applied in a key derivation process (e.g. PBKDF2).

strength {("medium"|"strict"|"high"|"strong" |"stronger"|"galaxy")} - It is a combination of each of the options above.

IMPORTANT*: All of the above options, if defined for encryption, must be defined in the same way for decryption.
IMPORTANT*: If you choose to use the STRENGTH option, all others must be ignored.
1
  • import
  • MerlinDB,
  • {
  • Schema
  • }
  • from
  • "@chrisaxxwell/merlin-db";
    2
  • //Or if you are using 'merlindb.max.js' just call 'new MerlinDB()';
  • 3
    4
  • const
  • merlin =
  • new
  • MerlinDB(
  • )
  • ;
    5merlin
  • .connect(
  • "MY-SHOP-DATABASE"
  • )
  • ;
    6
    7
  • const
  • UserSchema =
  • Schema(
  • {
  •   
    8  
  • name:
  • String
  • ,
    9  
  • cardNumber:
  • {
  • 10      
  • type:
  • Array
  • ,
    11      
  • //For encrypt the type must be an array
  • 12      
  • encrypt:
  • {
  • 13        
  • //Any option used here must be used in the decrypt in the same way
  • 14        
  • strength:
  • "medium"
    15      
  • }
  • 16  
  • }
  • ,
    17
  • }
  • )
  • ;
    18
    19
  • var
  • dataModel = merlin
  • .model(
  • "Data", UserSchema
  • )
  • ;

    🔮Encryption:

    Rules:

    The first index is the value to be encrypted;
    The second index is the secret key to be encrypted.
    1dataModel
  • .insert(
  • {
  • 2  
  • name:
  • "Sam",
    3  
  • //It needs to be an array, where the first index is the value and the second will be the secret key
  • 4  
  • //cardNumber: ["5534 6544 7234 4323", <your-secret-key>],
  • 5  
  • cardNumber:
  • ["
  • 5534
  • 6544
  • 7234
  • 4323
  • ", 'I-Love-Cold-French-Fries-EatingAt-3Am'],
    6  
  • //Or
  • 7  
  • cardNumber:
  • ["
  • 5534
  • 6544
  • 7234
  • 4323
  • ", '5atY23TtK8755EfG...'],
    8
    9
  • }
  • )
  • .then(
  • e =>
  • {
  • 10   console
  • .log(
  • e
  • )
  • ;
    11  
  • //returns
  • 12  
  • {
  • 13  
  • "acknowledged":
  • true
  • ,
    14  
  • "insertedId":
  • "667a621dTW96aW5c2f9f9211",
    15  
  • data:
  • {
  • 16      
  • "cardNumber":
  • "en9yjVibqbBg4Dbg1fD+K8iTJqCpX/nlsyWa9JVGK7Q=",
    17      
  • "id_":
  • "667a621dTW96aW5c2f9f9211"
    18  
  • }
  • 19
  • }
  • )
  • ;

    🔮Decryption:

    In the options parameter, define decrypt with the options:

    { secretKey } (required*): It is the secret key used when encrypting;
    { fields } (required*): These are the fields that were encrypted;

    { salt }: If defined in the encryption, this option is mandatory for decryption.
    { iterations }: If defined in the encryption, this option is mandatory for decryption.
    { strength }: If defined in the encryption, this option is mandatory for decryption.
    1dataModel
  • .find(
  • 2  
  • //query
  • 3  
  • {
  • name:
  • "Sam"
  • }
  • ,
    4
    5  
  • //options
  • 6  
  • {
  • 7      
  • decrypt:
  • {
  • 8        
  • secretKey:
  • <your-secret-key>,
    9        
  • fields:
  • [ "cardNumber" ],
    10        
  • strength:
  • "medium"
    11      
  • }
  • 12  
  • }
  • 13
  • )
  • .then(
  • e =>
  • {
  • 14   console
  • .log(
  • e
  • )
  • ;
    15  
  • //returns
  • 16  
  • {
  • 17      
  • name:
  • "Sam",
    18      
  • cardNumber:
  • "
  • 5534
  • 6544
  • 7234
  • 4323
  • "
    19
  • }
  • )
  • .catch(
  • e =>
  • {
  • 20   console
  • .log(
  • e
  • )
  • ;
    21  
  • //returns
  • 22  
  • {
  • 23      
  • message:
  • "Invalid 'secretKey'",
    24      
  • cardNumber:
  • "en9yjVibqbBg4Dbg1fD+K8iTJqCpX/nlsyWa9JVGK7Q="
    25  
  • }
  • 26
  • }
  • )
  • ;

    Curiosities about AES

    Suppose you encrypted a card number with a random key using AES and a hacker obtains the encrypted value (ciphertext), the hacker's ability to discover the card number It will depend on some factors, let's see:


    Key Security: If the hacker does not have access to the encryption key (secretKey) generated when encrypting the data, it is extremely difficult to decipher the encrypted value.

    Key Protection: The encryption key must be stored and managed securely.

    Learn more about it at (AES Wikipedia).