mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 00:29:34 +00:00
feat(fips): requested changes (function renaming)
This commit is contained in:
@@ -221,122 +221,134 @@ const cryptographyFactory = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const decryptSymmetric = ({ ciphertext, iv, tag, key, keySize }: TDecryptSymmetricInput): string => {
|
||||
let decipher;
|
||||
const symmetric = () => {
|
||||
const decrypt = ({ ciphertext, iv, tag, key, keySize }: TDecryptSymmetricInput): string => {
|
||||
let decipher;
|
||||
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
// Not ideal: 128-bit hex key (32 chars) gets interpreted as 32 UTF-8 bytes (256 bits)
|
||||
// This works but reduces effective key entropy from 256 to 128 bits
|
||||
decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, key, Buffer.from(iv, "base64"));
|
||||
} else {
|
||||
const secretKey = crypto.createSecretKey(key, "base64");
|
||||
decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, secretKey, Buffer.from(iv, "base64"));
|
||||
}
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
// Not ideal: 128-bit hex key (32 chars) gets interpreted as 32 UTF-8 bytes (256 bits)
|
||||
// This works but reduces effective key entropy from 256 to 128 bits
|
||||
decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, key, Buffer.from(iv, "base64"));
|
||||
} else {
|
||||
const secretKey = crypto.createSecretKey(key, "base64");
|
||||
decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, secretKey, Buffer.from(iv, "base64"));
|
||||
}
|
||||
|
||||
decipher.setAuthTag(Buffer.from(tag, "base64"));
|
||||
let cleartext = decipher.update(ciphertext, "base64", "utf8");
|
||||
cleartext += decipher.final("utf8");
|
||||
decipher.setAuthTag(Buffer.from(tag, "base64"));
|
||||
let cleartext = decipher.update(ciphertext, "base64", "utf8");
|
||||
cleartext += decipher.final("utf8");
|
||||
|
||||
return cleartext;
|
||||
};
|
||||
return cleartext;
|
||||
};
|
||||
|
||||
const encryptSymmetric = ({ plaintext, key, keySize }: TEncryptSymmetricInput) => {
|
||||
let iv;
|
||||
let cipher;
|
||||
const encrypt = ({ plaintext, key, keySize }: TEncryptSymmetricInput) => {
|
||||
let iv;
|
||||
let cipher;
|
||||
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16);
|
||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, key, iv);
|
||||
} else {
|
||||
iv = crypto.randomBytes(IV_BYTES_SIZE);
|
||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, crypto.createSecretKey(key, "base64"), iv);
|
||||
}
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16);
|
||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, key, iv);
|
||||
} else {
|
||||
iv = crypto.randomBytes(IV_BYTES_SIZE);
|
||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, crypto.createSecretKey(key, "base64"), iv);
|
||||
}
|
||||
|
||||
let ciphertext = cipher.update(plaintext, "utf8", "base64");
|
||||
ciphertext += cipher.final("base64");
|
||||
let ciphertext = cipher.update(plaintext, "utf8", "base64");
|
||||
ciphertext += cipher.final("base64");
|
||||
|
||||
return {
|
||||
ciphertext,
|
||||
iv: iv.toString("base64"),
|
||||
tag: cipher.getAuthTag().toString("base64")
|
||||
};
|
||||
};
|
||||
|
||||
const encryptWithRootEncryptionKey = (data: string) => {
|
||||
const appCfg = getConfig();
|
||||
const rootEncryptionKey = appCfg.ROOT_ENCRYPTION_KEY;
|
||||
const encryptionKey = appCfg.ENCRYPTION_KEY;
|
||||
|
||||
if (rootEncryptionKey) {
|
||||
const { iv, tag, ciphertext } = encrypt({
|
||||
plaintext: data,
|
||||
key: rootEncryptionKey,
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
return {
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
||||
encoding: SecretKeyEncoding.BASE64
|
||||
};
|
||||
}
|
||||
if (encryptionKey) {
|
||||
const { iv, tag, ciphertext } = encrypt({
|
||||
plaintext: data,
|
||||
key: encryptionKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return {
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
||||
encoding: SecretKeyEncoding.UTF8
|
||||
};
|
||||
}
|
||||
throw new CryptographyError({
|
||||
message: "Missing both encryption keys"
|
||||
});
|
||||
};
|
||||
|
||||
const decryptWithRootEncryptionKey = <T = string>({
|
||||
keyEncoding,
|
||||
ciphertext,
|
||||
tag,
|
||||
iv
|
||||
}: Omit<TDecryptSymmetricInput, "key" | "keySize"> & {
|
||||
keyEncoding: SecretKeyEncoding;
|
||||
}) => {
|
||||
const appCfg = getConfig();
|
||||
// the or gate is used used in migration
|
||||
const rootEncryptionKey = appCfg?.ROOT_ENCRYPTION_KEY || process.env.ROOT_ENCRYPTION_KEY;
|
||||
const encryptionKey = appCfg?.ENCRYPTION_KEY || process.env.ENCRYPTION_KEY;
|
||||
if (rootEncryptionKey && keyEncoding === SecretKeyEncoding.BASE64) {
|
||||
const data = symmetric().decrypt({
|
||||
key: rootEncryptionKey,
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
return data as T;
|
||||
}
|
||||
if (encryptionKey && keyEncoding === SecretKeyEncoding.UTF8) {
|
||||
const data = symmetric().decrypt({
|
||||
key: encryptionKey,
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return data as T;
|
||||
}
|
||||
throw new CryptographyError({
|
||||
message: "Missing both encryption keys"
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
ciphertext,
|
||||
iv: iv.toString("base64"),
|
||||
tag: cipher.getAuthTag().toString("base64")
|
||||
decrypt,
|
||||
encrypt,
|
||||
encryptWithRootEncryptionKey,
|
||||
decryptWithRootEncryptionKey
|
||||
};
|
||||
};
|
||||
|
||||
const encryptWithRootEncryptionKey = (data: string) => {
|
||||
const appCfg = getConfig();
|
||||
const rootEncryptionKey = appCfg.ROOT_ENCRYPTION_KEY;
|
||||
const encryptionKey = appCfg.ENCRYPTION_KEY;
|
||||
|
||||
if (rootEncryptionKey) {
|
||||
const { iv, tag, ciphertext } = encryptSymmetric({
|
||||
plaintext: data,
|
||||
key: rootEncryptionKey,
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
return {
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
||||
encoding: SecretKeyEncoding.BASE64
|
||||
};
|
||||
}
|
||||
if (encryptionKey) {
|
||||
const { iv, tag, ciphertext } = encryptSymmetric({
|
||||
plaintext: data,
|
||||
key: encryptionKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return {
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
algorithm: SecretEncryptionAlgo.AES_256_GCM,
|
||||
encoding: SecretKeyEncoding.UTF8
|
||||
};
|
||||
}
|
||||
throw new CryptographyError({
|
||||
message: "Missing both encryption keys"
|
||||
});
|
||||
};
|
||||
|
||||
const decryptWithRootEncryptionKey = <T = string>({
|
||||
keyEncoding,
|
||||
ciphertext,
|
||||
tag,
|
||||
iv
|
||||
}: Omit<TDecryptSymmetricInput, "key" | "keySize"> & {
|
||||
keyEncoding: SecretKeyEncoding;
|
||||
}) => {
|
||||
const appCfg = getConfig();
|
||||
// the or gate is used used in migration
|
||||
const rootEncryptionKey = appCfg?.ROOT_ENCRYPTION_KEY || process.env.ROOT_ENCRYPTION_KEY;
|
||||
const encryptionKey = appCfg?.ENCRYPTION_KEY || process.env.ENCRYPTION_KEY;
|
||||
if (rootEncryptionKey && keyEncoding === SecretKeyEncoding.BASE64) {
|
||||
const data = decryptSymmetric({
|
||||
key: rootEncryptionKey,
|
||||
iv,
|
||||
tag,
|
||||
ciphertext,
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
return data as T;
|
||||
}
|
||||
if (encryptionKey && keyEncoding === SecretKeyEncoding.UTF8) {
|
||||
const data = decryptSymmetric({ key: encryptionKey, iv, tag, ciphertext, keySize: SymmetricKeySize.Bits128 });
|
||||
return data as T;
|
||||
}
|
||||
throw new CryptographyError({
|
||||
message: "Missing both encryption keys"
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
asymmetric,
|
||||
encryptWithRootEncryptionKey,
|
||||
decryptWithRootEncryptionKey,
|
||||
encryptSymmetric,
|
||||
decryptSymmetric
|
||||
symmetric
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -32,11 +32,13 @@ export const buildSecretBlindIndexFromName = async ({
|
||||
if (rootEncryptionKey && keyEncoding === SecretKeyEncoding.BASE64) {
|
||||
salt = crypto
|
||||
.encryption()
|
||||
.decryptSymmetric({ iv, ciphertext, key: rootEncryptionKey, tag, keySize: SymmetricKeySize.Bits256 });
|
||||
.symmetric()
|
||||
.decrypt({ iv, ciphertext, key: rootEncryptionKey, tag, keySize: SymmetricKeySize.Bits256 });
|
||||
} else if (encryptionKey && keyEncoding === SecretKeyEncoding.UTF8) {
|
||||
salt = crypto
|
||||
.encryption()
|
||||
.decryptSymmetric({ iv, ciphertext, key: encryptionKey, tag, keySize: SymmetricKeySize.Bits128 });
|
||||
.symmetric()
|
||||
.decrypt({ iv, ciphertext, key: encryptionKey, tag, keySize: SymmetricKeySize.Bits128 });
|
||||
}
|
||||
if (!salt) throw new Error("Missing secret blind index key");
|
||||
|
||||
|
||||
@@ -74,11 +74,14 @@ export const generateUserSrpKeys = async (
|
||||
ciphertext: encryptedPrivateKey,
|
||||
iv: encryptedPrivateKeyIV,
|
||||
tag: encryptedPrivateKeyTag
|
||||
} = crypto.encryption().encryptSymmetric({
|
||||
plaintext: privateKey,
|
||||
key: key.toString("base64"),
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
} = crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.encrypt({
|
||||
plaintext: privateKey,
|
||||
key: key.toString("base64"),
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
|
||||
// create the protected key by encrypting the symmetric key
|
||||
// [key] with the derived key
|
||||
@@ -86,11 +89,14 @@ export const generateUserSrpKeys = async (
|
||||
ciphertext: protectedKey,
|
||||
iv: protectedKeyIV,
|
||||
tag: protectedKeyTag
|
||||
} = crypto.encryption().encryptSymmetric({
|
||||
plaintext: key.toString("hex"),
|
||||
key: derivedKey.toString("base64"),
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
} = crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.encrypt({
|
||||
plaintext: key.toString("hex"),
|
||||
key: derivedKey.toString("base64"),
|
||||
keySize: SymmetricKeySize.Bits256
|
||||
});
|
||||
|
||||
return {
|
||||
protectedKey,
|
||||
@@ -121,13 +127,16 @@ export const getUserPrivateKey = async (
|
||||
>
|
||||
) => {
|
||||
if (user.encryptionVersion === UserEncryption.V1) {
|
||||
return crypto.encryption().decryptSymmetric({
|
||||
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"),
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decrypt({
|
||||
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"),
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
}
|
||||
if (
|
||||
user.encryptionVersion === UserEncryption.V2 &&
|
||||
@@ -145,7 +154,7 @@ export const getUserPrivateKey = async (
|
||||
raw: true
|
||||
});
|
||||
if (!derivedKey) throw new Error("Failed to derive key from password");
|
||||
const key = crypto.encryption().decryptSymmetric({
|
||||
const key = crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: user.protectedKey,
|
||||
iv: user.protectedKeyIV,
|
||||
tag: user.protectedKeyTag,
|
||||
@@ -153,13 +162,16 @@ export const getUserPrivateKey = async (
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
|
||||
const privateKey = crypto.encryption().decryptSymmetric({
|
||||
ciphertext: user.encryptedPrivateKey,
|
||||
iv: user.iv,
|
||||
tag: user.tag,
|
||||
key: Buffer.from(key, "hex"),
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
const privateKey = crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decrypt({
|
||||
ciphertext: user.encryptedPrivateKey,
|
||||
iv: user.iv,
|
||||
tag: user.tag,
|
||||
key: Buffer.from(key, "hex"),
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return privateKey;
|
||||
}
|
||||
throw new Error(`GetUserPrivateKey: Encryption version not found`);
|
||||
|
||||
Reference in New Issue
Block a user