mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 23:33:31 +00:00
add support for decrypting AES-ECB mode (#6476)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { DecryptParameters } from "@bitwarden/common/platform/models/domain/decrypt-parameters";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
|
||||
import { NodeCryptoFunctionService } from "./node-crypto-function.service";
|
||||
@@ -164,7 +165,7 @@ describe("NodeCrypto Function Service", () => {
|
||||
testCompare(true);
|
||||
});
|
||||
|
||||
describe("aesEncrypt", () => {
|
||||
describe("aesEncrypt CBC mode", () => {
|
||||
it("should successfully encrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = makeStaticByteArray(16);
|
||||
@@ -181,30 +182,51 @@ describe("NodeCrypto Function Service", () => {
|
||||
const value = "EncryptMe!";
|
||||
const data = Utils.fromUtf8ToArray(value);
|
||||
const encValue = await nodeCryptoFunctionService.aesEncrypt(data, iv, key);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv, key);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv, key, "cbc");
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecryptFast", () => {
|
||||
describe("aesDecryptFast CBC mode", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = Utils.fromBufferToB64(makeStaticByteArray(16));
|
||||
const symKey = new SymmetricCryptoKey(makeStaticByteArray(32));
|
||||
const data = "ByUF8vhyX4ddU9gcooznwA==";
|
||||
const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params, "cbc");
|
||||
expect(decValue).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecrypt", () => {
|
||||
describe("aesDecryptFast ECB mode", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const params = new DecryptParameters<Uint8Array>();
|
||||
params.encKey = makeStaticByteArray(32);
|
||||
params.data = Utils.fromB64ToArray("z5q2XSxYCdQFdI+qK2yLlw==");
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params, "ecb");
|
||||
expect(decValue).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecrypt CBC mode", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const iv = makeStaticByteArray(16);
|
||||
const key = makeStaticByteArray(32);
|
||||
const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA==");
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(data, iv, key);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(data, iv, key, "cbc");
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecrypt ECB mode", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = makeStaticByteArray(32);
|
||||
const data = Utils.fromB64ToArray("z5q2XSxYCdQFdI+qK2yLlw==");
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(data, null, key, "ecb");
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -189,16 +189,24 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
|
||||
return p;
|
||||
}
|
||||
|
||||
async aesDecryptFast(parameters: DecryptParameters<Uint8Array>): Promise<string> {
|
||||
const decBuf = await this.aesDecrypt(parameters.data, parameters.iv, parameters.encKey);
|
||||
async aesDecryptFast(
|
||||
parameters: DecryptParameters<Uint8Array>,
|
||||
mode: "cbc" | "ecb"
|
||||
): Promise<string> {
|
||||
const decBuf = await this.aesDecrypt(parameters.data, parameters.iv, parameters.encKey, mode);
|
||||
return Utils.fromBufferToUtf8(decBuf);
|
||||
}
|
||||
|
||||
aesDecrypt(data: Uint8Array, iv: Uint8Array, key: Uint8Array): Promise<Uint8Array> {
|
||||
aesDecrypt(
|
||||
data: Uint8Array,
|
||||
iv: Uint8Array,
|
||||
key: Uint8Array,
|
||||
mode: "cbc" | "ecb"
|
||||
): Promise<Uint8Array> {
|
||||
const nodeData = this.toNodeBuffer(data);
|
||||
const nodeIv = this.toNodeBuffer(iv);
|
||||
const nodeIv = mode === "ecb" ? null : this.toNodeBuffer(iv);
|
||||
const nodeKey = this.toNodeBuffer(key);
|
||||
const decipher = crypto.createDecipheriv("aes-256-cbc", nodeKey, nodeIv);
|
||||
const decipher = crypto.createDecipheriv(this.toNodeCryptoAesMode(mode), nodeKey, nodeIv);
|
||||
const decBuf = Buffer.concat([decipher.update(nodeData), decipher.final()]);
|
||||
return Promise.resolve(this.toUint8Buffer(decBuf));
|
||||
}
|
||||
@@ -326,4 +334,8 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
|
||||
const publicKey = forge.pki.publicKeyFromAsn1(asn1);
|
||||
return forge.pki.publicKeyToPem(publicKey);
|
||||
}
|
||||
|
||||
private toNodeCryptoAesMode(mode: "cbc" | "ecb"): string {
|
||||
return mode === "cbc" ? "aes-256-cbc" : "aes-256-ecb";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user