mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 22:33:35 +00:00
[PS-2365] Kdf Configuration Options for Argon2 (#4578)
* Implement argon2 config * Remove argon2 webassembly warning * Replace magic numbers by enum * Implement kdf configuration * Update UI according to design feedback * Further updates to follow design feedback * Add oxford comma in argon2 description * Fix typos in argon2 descriptions * move key creation into promise with API call * change casing on PBKDF2 * general improvements * kdf config on set pin component * SHA-256 hash argon2 salt * Change argon2 defaults * Change argon2 salt hash to cryptoFunctionService * Fix isLowKdfIteration check --------- Co-authored-by: Kyle Spearrin <kyle.spearrin@gmail.com> Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.serv
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { KdfType } from "@bitwarden/common/enums/kdfType";
|
||||
import { EncString } from "@bitwarden/common/models/domain/enc-string";
|
||||
import { KdfConfig } from "@bitwarden/common/models/domain/kdf-config";
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/models/domain/master-password-policy-options";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetric-crypto-key";
|
||||
|
||||
@@ -27,7 +28,7 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
|
||||
|
||||
protected email: string;
|
||||
protected kdf: KdfType;
|
||||
protected kdfIterations: number;
|
||||
protected kdfConfig: KdfConfig;
|
||||
|
||||
protected destroy$ = new Subject<void>();
|
||||
|
||||
@@ -70,14 +71,14 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
|
||||
if (this.kdf == null) {
|
||||
this.kdf = await this.stateService.getKdfType();
|
||||
}
|
||||
if (this.kdfIterations == null) {
|
||||
this.kdfIterations = await this.stateService.getKdfIterations();
|
||||
if (this.kdfConfig == null) {
|
||||
this.kdfConfig = await this.stateService.getKdfConfig();
|
||||
}
|
||||
const key = await this.cryptoService.makeKey(
|
||||
this.masterPassword,
|
||||
email.trim().toLowerCase(),
|
||||
this.kdf,
|
||||
this.kdfIterations
|
||||
this.kdfConfig
|
||||
);
|
||||
const masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, key);
|
||||
|
||||
|
||||
@@ -136,13 +136,13 @@ export class LockComponent implements OnInit, OnDestroy {
|
||||
let failed = true;
|
||||
try {
|
||||
const kdf = await this.stateService.getKdfType();
|
||||
const kdfIterations = await this.stateService.getKdfIterations();
|
||||
const kdfConfig = await this.stateService.getKdfConfig();
|
||||
if (this.pinSet[0]) {
|
||||
const key = await this.cryptoService.makeKeyFromPin(
|
||||
this.pin,
|
||||
this.email,
|
||||
kdf,
|
||||
kdfIterations,
|
||||
kdfConfig,
|
||||
await this.stateService.getDecryptedPinProtected()
|
||||
);
|
||||
const encKey = await this.cryptoService.getEncKey(key);
|
||||
@@ -153,12 +153,7 @@ export class LockComponent implements OnInit, OnDestroy {
|
||||
await this.setKeyAndContinue(key);
|
||||
}
|
||||
} else {
|
||||
const key = await this.cryptoService.makeKeyFromPin(
|
||||
this.pin,
|
||||
this.email,
|
||||
kdf,
|
||||
kdfIterations
|
||||
);
|
||||
const key = await this.cryptoService.makeKeyFromPin(this.pin, this.email, kdf, kdfConfig);
|
||||
failed = false;
|
||||
await this.setKeyAndContinue(key);
|
||||
}
|
||||
@@ -194,14 +189,9 @@ export class LockComponent implements OnInit, OnDestroy {
|
||||
|
||||
private async doUnlockWithMasterPassword() {
|
||||
const kdf = await this.stateService.getKdfType();
|
||||
const kdfIterations = await this.stateService.getKdfIterations();
|
||||
const kdfConfig = await this.stateService.getKdfConfig();
|
||||
|
||||
const key = await this.cryptoService.makeKey(
|
||||
this.masterPassword,
|
||||
this.email,
|
||||
kdf,
|
||||
kdfIterations
|
||||
);
|
||||
const key = await this.cryptoService.makeKey(this.masterPassword, this.email, kdf, kdfConfig);
|
||||
const storedKeyHash = await this.cryptoService.getKeyHash();
|
||||
|
||||
let passwordValid = false;
|
||||
@@ -244,7 +234,7 @@ export class LockComponent implements OnInit, OnDestroy {
|
||||
const protectedPin = await this.stateService.getProtectedPin();
|
||||
const encKey = await this.cryptoService.getEncKey(key);
|
||||
const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey);
|
||||
const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfIterations);
|
||||
const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfConfig);
|
||||
await this.stateService.setDecryptedPinProtected(
|
||||
await this.cryptoService.encrypt(key.key, pinKey)
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { DEFAULT_KDF_TYPE, DEFAULT_PBKDF2_ITERATIONS } from "@bitwarden/common/enums/kdfType";
|
||||
import { DEFAULT_KDF_CONFIG, DEFAULT_KDF_TYPE } from "@bitwarden/common/enums/kdfType";
|
||||
import { PasswordLogInCredentials } from "@bitwarden/common/models/domain/log-in-credentials";
|
||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||
import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request";
|
||||
@@ -269,8 +269,8 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
): Promise<RegisterRequest> {
|
||||
const hint = this.formGroup.value.hint;
|
||||
const kdf = DEFAULT_KDF_TYPE;
|
||||
const kdfIterations = DEFAULT_PBKDF2_ITERATIONS;
|
||||
const key = await this.cryptoService.makeKey(masterPassword, email, kdf, kdfIterations);
|
||||
const kdfConfig = DEFAULT_KDF_CONFIG;
|
||||
const key = await this.cryptoService.makeKey(masterPassword, email, kdf, kdfConfig);
|
||||
const encKey = await this.cryptoService.makeEncKey(key);
|
||||
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
|
||||
const keys = await this.cryptoService.makeKeyPair(encKey[0]);
|
||||
@@ -280,10 +280,12 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
hashedPassword,
|
||||
hint,
|
||||
encKey[1].encryptedString,
|
||||
kdf,
|
||||
kdfIterations,
|
||||
this.referenceData,
|
||||
this.captchaToken
|
||||
this.captchaToken,
|
||||
kdf,
|
||||
kdfConfig.iterations,
|
||||
kdfConfig.memory,
|
||||
kdfConfig.parallelism
|
||||
);
|
||||
request.keys = new KeysRequest(keys[0], keys[1].encryptedString);
|
||||
const orgInvite = await this.stateService.getOrganizationInvitation();
|
||||
|
||||
@@ -16,7 +16,7 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.serv
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { HashPurpose } from "@bitwarden/common/enums/hashPurpose";
|
||||
import { DEFAULT_KDF_TYPE, DEFAULT_PBKDF2_ITERATIONS } from "@bitwarden/common/enums/kdfType";
|
||||
import { DEFAULT_KDF_TYPE, DEFAULT_KDF_CONFIG } from "@bitwarden/common/enums/kdfType";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetric-crypto-key";
|
||||
@@ -93,7 +93,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||
|
||||
async setupSubmitActions() {
|
||||
this.kdf = DEFAULT_KDF_TYPE;
|
||||
this.kdfIterations = DEFAULT_PBKDF2_ITERATIONS;
|
||||
this.kdfConfig = DEFAULT_KDF_CONFIG;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,12 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||
masterPasswordHash,
|
||||
encKey[1].encryptedString,
|
||||
this.hint,
|
||||
this.kdf,
|
||||
this.kdfIterations,
|
||||
this.identifier,
|
||||
new KeysRequest(keys[0], keys[1].encryptedString)
|
||||
new KeysRequest(keys[0], keys[1].encryptedString),
|
||||
this.kdf,
|
||||
this.kdfConfig.iterations,
|
||||
this.kdfConfig.memory,
|
||||
this.kdfConfig.parallelism
|
||||
);
|
||||
try {
|
||||
if (this.resetPasswordAutoEnroll) {
|
||||
@@ -173,7 +175,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||
keys: [string, EncString]
|
||||
) {
|
||||
await this.stateService.setKdfType(this.kdf);
|
||||
await this.stateService.setKdfIterations(this.kdfIterations);
|
||||
await this.stateService.setKdfConfig(this.kdfConfig);
|
||||
await this.cryptoService.setKey(key);
|
||||
await this.cryptoService.setEncKey(encKey[1].encryptedString);
|
||||
await this.cryptoService.setEncPrivateKey(keys[1].encryptedString);
|
||||
|
||||
@@ -36,9 +36,9 @@ export class SetPinComponent implements OnInit {
|
||||
}
|
||||
|
||||
const kdf = await this.stateService.getKdfType();
|
||||
const kdfIterations = await this.stateService.getKdfIterations();
|
||||
const kdfConfig = await this.stateService.getKdfConfig();
|
||||
const email = await this.stateService.getEmail();
|
||||
const pinKey = await this.cryptoService.makePinKey(this.pin, email, kdf, kdfIterations);
|
||||
const pinKey = await this.cryptoService.makePinKey(this.pin, email, kdf, kdfConfig);
|
||||
const key = await this.cryptoService.getKey();
|
||||
const pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);
|
||||
if (this.masterPassOnRestart) {
|
||||
|
||||
@@ -86,7 +86,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
|
||||
}
|
||||
|
||||
this.kdf = await this.stateService.getKdfType();
|
||||
this.kdfIterations = await this.stateService.getKdfIterations();
|
||||
this.kdfConfig = await this.stateService.getKdfConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
|
||||
async setupSubmitActions(): Promise<boolean> {
|
||||
this.email = await this.stateService.getEmail();
|
||||
this.kdf = await this.stateService.getKdfType();
|
||||
this.kdfIterations = await this.stateService.getKdfIterations();
|
||||
this.kdfConfig = await this.stateService.getKdfConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
|
||||
this.masterPassword,
|
||||
this.email.trim().toLowerCase(),
|
||||
this.kdf,
|
||||
this.kdfIterations
|
||||
this.kdfConfig
|
||||
);
|
||||
const newPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user