mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[PM-20492] Refactor symmetric keys - remove key buffer representation, migrate consumers to .toEncoded() (#14371)
* Refactor encrypt service to expose key wrapping * Fix build * Undo ts strict removal * Fix wrong method being used to encrypt key material * Rename parameters and remove todo * Add summary to encrypt * Update libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/crypto/abstractions/encrypt.service.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add tests for unhappy paths * Add test coverage * Add links * Remove direct buffer access * Fix build on cli --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
This commit is contained in:
@@ -19,7 +19,6 @@ describe("SymmetricCryptoKey", () => {
|
||||
const cryptoKey = new SymmetricCryptoKey(key);
|
||||
|
||||
expect(cryptoKey).toEqual({
|
||||
key: key,
|
||||
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
innerKey: {
|
||||
type: EncryptionType.AesCbc256_B64,
|
||||
@@ -33,7 +32,6 @@ describe("SymmetricCryptoKey", () => {
|
||||
const cryptoKey = new SymmetricCryptoKey(key);
|
||||
|
||||
expect(cryptoKey).toEqual({
|
||||
key: key,
|
||||
keyB64:
|
||||
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==",
|
||||
innerKey: {
|
||||
|
||||
@@ -24,7 +24,6 @@ export type Aes256CbcKey = {
|
||||
export class SymmetricCryptoKey {
|
||||
private innerKey: Aes256CbcHmacKey | Aes256CbcKey;
|
||||
|
||||
key: Uint8Array;
|
||||
keyB64: string;
|
||||
|
||||
/**
|
||||
@@ -40,7 +39,6 @@ export class SymmetricCryptoKey {
|
||||
type: EncryptionType.AesCbc256_B64,
|
||||
encryptionKey: key,
|
||||
};
|
||||
this.key = key;
|
||||
this.keyB64 = this.toBase64();
|
||||
} else if (key.byteLength === 64) {
|
||||
this.innerKey = {
|
||||
@@ -48,7 +46,6 @@ export class SymmetricCryptoKey {
|
||||
encryptionKey: key.slice(0, 32),
|
||||
authenticationKey: key.slice(32),
|
||||
};
|
||||
this.key = key;
|
||||
this.keyB64 = this.toBase64();
|
||||
} else {
|
||||
throw new Error(`Unsupported encType/key length ${key.byteLength}`);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PBKDF2KdfConfig, Argon2KdfConfig } from "@bitwarden/key-management";
|
||||
|
||||
import { CryptoFunctionService } from "../../key-management/crypto/abstractions/crypto-function.service";
|
||||
import { CsprngArray } from "../../types/csprng";
|
||||
import { EncryptionType } from "../enums";
|
||||
|
||||
import { KeyGenerationService } from "./key-generation.service";
|
||||
|
||||
@@ -52,7 +53,7 @@ describe("KeyGenerationService", () => {
|
||||
|
||||
expect(salt).toEqual(inputSalt);
|
||||
expect(material).toEqual(inputMaterial);
|
||||
expect(derivedKey.key.length).toEqual(64);
|
||||
expect(derivedKey.inner().type).toEqual(EncryptionType.AesCbc256_HmacSha256_B64);
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -67,7 +68,7 @@ describe("KeyGenerationService", () => {
|
||||
|
||||
const key = await sut.deriveKeyFromMaterial(material, salt, purpose);
|
||||
|
||||
expect(key.key.length).toEqual(64);
|
||||
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_HmacSha256_B64);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,7 +82,7 @@ describe("KeyGenerationService", () => {
|
||||
|
||||
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
|
||||
|
||||
expect(key.key.length).toEqual(32);
|
||||
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64);
|
||||
});
|
||||
|
||||
it("should derive a 32 byte key from a password using argon2id", async () => {
|
||||
@@ -94,7 +95,7 @@ describe("KeyGenerationService", () => {
|
||||
|
||||
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
|
||||
|
||||
expect(key.key.length).toEqual(32);
|
||||
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { MasterKey, PinKey } from "@bitwarden/common/types/key";
|
||||
import { KdfConfig, PBKDF2KdfConfig, Argon2KdfConfig, KdfType } from "@bitwarden/key-management";
|
||||
|
||||
import { CryptoFunctionService } from "../../key-management/crypto/abstractions/crypto-function.service";
|
||||
@@ -78,10 +79,21 @@ export class KeyGenerationService implements KeyGenerationServiceAbstraction {
|
||||
return new SymmetricCryptoKey(key);
|
||||
}
|
||||
|
||||
async stretchKey(key: SymmetricCryptoKey): Promise<SymmetricCryptoKey> {
|
||||
async stretchKey(key: MasterKey | PinKey): Promise<SymmetricCryptoKey> {
|
||||
const newKey = new Uint8Array(64);
|
||||
const encKey = await this.cryptoFunctionService.hkdfExpand(key.key, "enc", 32, "sha256");
|
||||
const macKey = await this.cryptoFunctionService.hkdfExpand(key.key, "mac", 32, "sha256");
|
||||
// Master key and pin key are always 32 bytes
|
||||
const encKey = await this.cryptoFunctionService.hkdfExpand(
|
||||
key.inner().encryptionKey,
|
||||
"enc",
|
||||
32,
|
||||
"sha256",
|
||||
);
|
||||
const macKey = await this.cryptoFunctionService.hkdfExpand(
|
||||
key.inner().encryptionKey,
|
||||
"mac",
|
||||
32,
|
||||
"sha256",
|
||||
);
|
||||
|
||||
newKey.set(new Uint8Array(encKey));
|
||||
newKey.set(new Uint8Array(macKey), 32);
|
||||
|
||||
Reference in New Issue
Block a user