cal.com icon indicating copy to clipboard operation
cal.com copied to clipboard

[CAL-2901] Symmetric encryption keys are weaker than they should be

Open nicktrn opened this issue 1 year ago • 7 comments

Issue Summary

https://github.com/calcom/cal.com/blob/7c237736365c188e1762691fa4376a5e71daeee5/.env.example#L88-L91

Currently, 24 random bytes are expanded via base64-encoding to match the required AES-256 key length of 32 bytes.

This is effectively AES-192 security (with two additional rounds).

Recommendations

diff --git a/.env.example b/.env.example
index 20bef8f8a..209740148 100644
--- a/.env.example
+++ b/.env.example
@@ -87,7 +87,7 @@ CRON_ENABLE_APP_SYNC=false
 
 # Application Key for symmetric encryption and decryption
 # must be 32 bytes for AES256 encryption algorithm
-# You can use: `openssl rand -base64 24` to generate one
+# You can use: `openssl rand -base64 32` to generate one
 CALENDSO_ENCRYPTION_KEY=
 
 # Intercom Config
diff --git a/packages/lib/crypto.ts b/packages/lib/crypto.ts
index d33f0c8f4..f662f22cc 100644
--- a/packages/lib/crypto.ts
+++ b/packages/lib/crypto.ts
@@ -13,7 +13,7 @@ const IV_LENGTH = 16; // AES blocksize
  * @returns Encrypted value using key
  */
 export const symmetricEncrypt = function (text: string, key: string) {
-  const _key = Buffer.from(key, "latin1");
+  const _key = Buffer.from(key, "base64");
   const iv = crypto.randomBytes(IV_LENGTH);
 
   const cipher = crypto.createCipheriv(ALGORITHM, _key, iv);
@@ -30,7 +30,7 @@ export const symmetricEncrypt = function (text: string, key: string) {
  * @param key Key used to decrypt value must be 32 bytes for AES256 encryption algorithm
  */
 export const symmetricDecrypt = function (text: string, key: string) {
-  const _key = Buffer.from(key, "latin1");
+  const _key = Buffer.from(key, "base64");
 
   const components = text.split(":");
   const iv_from_ciphertext = Buffer.from(components.shift() || "", OUTPUT_ENCODING);

The key encoding could also be chosen dynamically based on its length and an additional env var OLD_ENCRYPTION_KEY provided to migrate old secrets on-demand.

As part of the migration, I would recommend switching over to aes-256-gcm. Using non-authenticated AES in CBC mode is not recommended when GCM is available.

Could also take care of this at the same time:

  • #6028

CAL-2901

nicktrn avatar Aug 16 '23 14:08 nicktrn

/attempt #10805

MeenuyD avatar Aug 16 '23 15:08 MeenuyD

Sorry, there's nothing to attempt here, the labeling bot is just having fun.

nicktrn avatar Aug 16 '23 15:08 nicktrn

Maige update instructions to avoid bounties

PeerRich avatar Aug 17 '23 09:08 PeerRich

Here are your new instructions:

"Update instructions to avoid bounties"

Feel free to provide feedback.

maige-app[bot] avatar Aug 17 '23 09:08 maige-app[bot]

Maige update instructions to avoid "💎 Bounty"

PeerRich avatar Aug 17 '23 09:08 PeerRich

Here are your new instructions:

"Update instructions to avoid bounties and 💎 Bounty"

Feel free to provide feedback.

maige-app[bot] avatar Aug 17 '23 09:08 maige-app[bot]

Not stale.

nicktrn avatar Oct 27 '23 11:10 nicktrn