1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-17 09:59:41 +00:00

Include aes gcm encryption

key connector will always provide the asym keys and the clients will encapsulate a key and encrypt communications with it.
This commit is contained in:
Matt Gibson
2024-11-18 14:09:25 -08:00
parent 6a7c05ae12
commit 8ccf0b77ac
4 changed files with 122 additions and 1 deletions

View File

@@ -187,6 +187,47 @@ describe("NodeCrypto Function Service", () => {
});
});
describe("aes encrypt GCM mode", () => {
it("should successfully encrypt data", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const iv = makeStaticByteArray(12);
const key = makeStaticByteArray(32);
const data = Utils.fromUtf8ToArray("EncryptMe!");
const encValue = await cryptoFunctionService.aesGcmEncrypt(data, iv, key);
expect(encValue).toEqual(
new Uint8Array(
Buffer.concat([Utils.fromB64ToArray("Amy1abyVtlboYFBtLnDAzAwAgb3Qg2m4fMo="), iv]),
),
);
});
it("should successfully encrypt with aad", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const iv = makeStaticByteArray(12);
const key = makeStaticByteArray(32);
const data = Utils.fromUtf8ToArray("EncryptMe!");
const aad = Utils.fromUtf8ToArray("aad");
const encValue = await cryptoFunctionService.aesGcmEncrypt(data, iv, key, aad);
expect(encValue).toEqual(
new Uint8Array(
Buffer.concat([Utils.fromB64ToArray("Amy1abyVtlboYJTbBTRtNtA4JtxBgjhhSCE="), iv]),
),
);
});
it("should successfully encrypt and then decrypt data", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const iv = makeStaticByteArray(12);
const key = makeStaticByteArray(32);
const value = "EncryptMe!";
const data = Utils.fromUtf8ToArray(value);
const encAndIv = new Uint8Array(await cryptoFunctionService.aesGcmEncrypt(data, iv, key));
const envValue = encAndIv.slice(0, encAndIv.length - 12);
const decValue = await cryptoFunctionService.aesDecrypt(envValue, iv, key, "gcm");
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
});
});
describe("aesDecryptFast CBC mode", () => {
it("should successfully decrypt data", async () => {
const nodeCryptoFunctionService = new NodeCryptoFunctionService();

View File

@@ -163,6 +163,25 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
return Promise.resolve(this.toUint8Buffer(encBuf));
}
async aesGcmEncrypt(
data: Uint8Array,
iv: Uint8Array,
key: Uint8Array,
additionalData?: Uint8Array,
): Promise<Uint8Array> {
const nodeData = this.toNodeBuffer(data);
const nodeIv = this.toNodeBuffer(iv);
const nodeKey = this.toNodeBuffer(key);
const cipher = crypto.createCipheriv("aes-256-gcm", nodeKey, nodeIv, { authTagLength: 16 });
if (additionalData != null) {
const nodeAdditionalData = this.toNodeBuffer(additionalData);
cipher.setAAD(nodeAdditionalData);
}
const encBuf = Buffer.concat([cipher.update(nodeData), cipher.final()]);
const tag = cipher.getAuthTag();
return Promise.resolve(this.toUint8Buffer(Buffer.concat([encBuf, tag, nodeIv])));
}
aesDecryptFastParameters(
data: string,
iv: string,
@@ -318,7 +337,7 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
if (typeof value === "string") {
buf = Utils.fromUtf8ToArray(value);
} else {
buf = value;
buf = new Uint8Array(value);
}
return buf;
}