diff --git a/backend/src/lib/crypto/srp.ts b/backend/src/lib/crypto/srp.ts index 8d7ea656a..29f716306 100644 --- a/backend/src/lib/crypto/srp.ts +++ b/backend/src/lib/crypto/srp.ts @@ -101,33 +101,51 @@ export const getUserPrivateKey = async ( password: string, user: Pick< TUserEncryptionKeys, - "protectedKeyTag" | "protectedKey" | "protectedKeyIV" | "encryptedPrivateKey" | "iv" | "salt" | "tag" + | "protectedKeyTag" + | "protectedKey" + | "protectedKeyIV" + | "encryptedPrivateKey" + | "iv" + | "salt" + | "tag" + | "encryptionVersion" > ) => { - const derivedKey = await argon2.hash(password, { - salt: Buffer.from(user.salt), - memoryCost: 65536, - timeCost: 3, - parallelism: 1, - hashLength: 32, - type: argon2.argon2id, - raw: true - }); - if (!derivedKey) throw new Error("Failed to derive key from password"); - const key = decryptSymmetric128BitHexKeyUTF8({ - ciphertext: user.protectedKey as string, - iv: user.protectedKeyIV as string, - tag: user.protectedKeyTag as string, - key: derivedKey - }); + if (user.encryptionVersion === 1) { + return decryptSymmetric128BitHexKeyUTF8({ + ciphertext: user.encryptedPrivateKey, + iv: user.iv, + tag: user.tag, + key: password.slice(0, 32).padStart(32 + (password.slice(0, 32).length - new Blob([password]).size), "0") + }); + } + if (user.encryptionVersion === 2 && user.protectedKey && user.protectedKeyIV && user.protectedKeyTag) { + const derivedKey = await argon2.hash(password, { + salt: Buffer.from(user.salt), + memoryCost: 65536, + timeCost: 3, + parallelism: 1, + hashLength: 32, + type: argon2.argon2id, + raw: true + }); + if (!derivedKey) throw new Error("Failed to derive key from password"); + const key = decryptSymmetric128BitHexKeyUTF8({ + ciphertext: user.protectedKey, + iv: user.protectedKeyIV, + tag: user.protectedKeyTag, + key: derivedKey + }); - const privateKey = decryptSymmetric128BitHexKeyUTF8({ - ciphertext: user.encryptedPrivateKey, - iv: user.iv, - tag: user.tag, - key: Buffer.from(key, "hex") - }); - return privateKey; + const privateKey = decryptSymmetric128BitHexKeyUTF8({ + ciphertext: user.encryptedPrivateKey, + iv: user.iv, + tag: user.tag, + key: Buffer.from(key, "hex") + }); + return privateKey; + } + throw new Error(`GetUserPrivateKey: Encryption version not found`); }; export const buildUserProjectKey = async (privateKey: string, publickey: string) => { diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 29a2a176f..c0a2e4388 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -9,6 +9,7 @@ import { generateSrpServerKey, srpCheckClientProof } from "@app/lib/crypto"; import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { getUserPrivateKey } from "@app/lib/crypto/srp"; import { BadRequestError, DatabaseError, UnauthorizedError } from "@app/lib/errors"; +import { logger } from "@app/lib/logger"; import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { TTokenDALFactory } from "../auth-token/auth-token-dal"; @@ -258,7 +259,10 @@ export const authLoginServiceFactory = ({ }); // from password decrypt the private key if (password) { - const privateKey = await getUserPrivateKey(password, userEnc); + const privateKey = await getUserPrivateKey(password, userEnc).catch((err) => { + logger.error(err, `private key generation failed for user id - ${user.id} and email -${user.email}`); + return ""; + }); const hashedPassword = await bcrypt.hash(password, cfg.BCRYPT_SALT_ROUND); const { iv, tag, ciphertext, encoding } = infisicalSymmetricEncypt(privateKey); await userDAL.updateUserEncryptionByUserId(userEnc.userId, { diff --git a/backend/src/services/auth/auth-signup-service.ts b/backend/src/services/auth/auth-signup-service.ts index 8cf2c9d34..0f1c65aca 100644 --- a/backend/src/services/auth/auth-signup-service.ts +++ b/backend/src/services/auth/auth-signup-service.ts @@ -165,7 +165,8 @@ export const authSignupServiceFactory = ({ protectedKeyTag, encryptedPrivateKey, iv: encryptedPrivateKeyIV, - tag: encryptedPrivateKeyTag + tag: encryptedPrivateKeyTag, + encryptionVersion: 2 }); const { tag, encoding, ciphertext, iv } = infisicalSymmetricEncypt(privateKey); const updateduser = await authDAL.transaction(async (tx) => { @@ -325,7 +326,8 @@ export const authSignupServiceFactory = ({ protectedKeyTag, encryptedPrivateKey, iv: encryptedPrivateKeyIV, - tag: encryptedPrivateKeyTag + tag: encryptedPrivateKeyTag, + encryptionVersion: 2 }); const { tag, encoding, ciphertext, iv } = infisicalSymmetricEncypt(privateKey); const updateduser = await authDAL.transaction(async (tx) => { diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index f1d931b20..27e198d85 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -98,6 +98,7 @@ export const superAdminServiceFactory = ({ if (existingUser) throw new BadRequestError({ name: "Admin sign up", message: "User already exist" }); const privateKey = await getUserPrivateKey(password, { + encryptionVersion: 2, salt, protectedKey, protectedKeyIV,