mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
[PM-3565] Enforce higher minimum KDF (#6440)
Changes minimum iterations for PBKDF2 to 600 000. Also converts the constants into ranges to ensure there is only a single place for all checks.
This commit is contained in:
@@ -73,6 +73,10 @@ export class ChangeKdfConfirmationComponent {
|
||||
const masterKey = await this.cryptoService.getOrDeriveMasterKey(masterPassword);
|
||||
request.masterPasswordHash = await this.cryptoService.hashMasterKey(masterPassword, masterKey);
|
||||
const email = await this.stateService.getEmail();
|
||||
|
||||
// Ensure the KDF config is valid.
|
||||
this.cryptoService.validateKdfConfig(this.kdf, this.kdfConfig);
|
||||
|
||||
const newMasterKey = await this.cryptoService.makeMasterKey(
|
||||
masterPassword,
|
||||
email,
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
<input
|
||||
id="kdfMemory"
|
||||
type="number"
|
||||
min="16"
|
||||
max="1024"
|
||||
[min]="ARGON2_MEMORY.min"
|
||||
[max]="ARGON2_MEMORY.max"
|
||||
name="Memory"
|
||||
class="form-control mb-3"
|
||||
[(ngModel)]="kdfConfig.memory"
|
||||
@@ -57,8 +57,8 @@
|
||||
<input
|
||||
id="kdfIterations"
|
||||
type="number"
|
||||
min="100000"
|
||||
max="2000000"
|
||||
[min]="PBKDF2_ITERATIONS.min"
|
||||
[max]="PBKDF2_ITERATIONS.max"
|
||||
name="KdfIterations"
|
||||
class="form-control"
|
||||
[(ngModel)]="kdfConfig.iterations"
|
||||
@@ -70,8 +70,8 @@
|
||||
<input
|
||||
id="iterations"
|
||||
type="number"
|
||||
min="2"
|
||||
max="10"
|
||||
[min]="ARGON2_ITERATIONS.min"
|
||||
[max]="ARGON2_ITERATIONS.max"
|
||||
name="Iterations"
|
||||
class="form-control mb-3"
|
||||
[(ngModel)]="kdfConfig.iterations"
|
||||
@@ -81,8 +81,8 @@
|
||||
<input
|
||||
id="kdfParallelism"
|
||||
type="number"
|
||||
min="1"
|
||||
max="16"
|
||||
[min]="ARGON2_PARALLELISM.min"
|
||||
[max]="ARGON2_PARALLELISM.max"
|
||||
name="Parallelism"
|
||||
class="form-control"
|
||||
[(ngModel)]="kdfConfig.parallelism"
|
||||
@@ -94,7 +94,7 @@
|
||||
<div class="col-12">
|
||||
<ng-container *ngIf="kdf == kdfType.PBKDF2_SHA256">
|
||||
<p class="small form-text text-muted">
|
||||
{{ "kdfIterationsDesc" | i18n: (recommendedPbkdf2Iterations | number) }}
|
||||
{{ "kdfIterationsDesc" | i18n: (PBKDF2_ITERATIONS.defaultValue | number) }}
|
||||
</p>
|
||||
<bit-callout type="warning">
|
||||
{{ "kdfIterationsWarning" | i18n: (100000 | number) }}
|
||||
|
||||
@@ -4,10 +4,10 @@ import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import {
|
||||
DEFAULT_KDF_CONFIG,
|
||||
DEFAULT_PBKDF2_ITERATIONS,
|
||||
DEFAULT_ARGON2_ITERATIONS,
|
||||
DEFAULT_ARGON2_MEMORY,
|
||||
DEFAULT_ARGON2_PARALLELISM,
|
||||
PBKDF2_ITERATIONS,
|
||||
ARGON2_ITERATIONS,
|
||||
ARGON2_MEMORY,
|
||||
ARGON2_PARALLELISM,
|
||||
KdfType,
|
||||
} from "@bitwarden/common/platform/enums";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
@@ -23,7 +23,12 @@ export class ChangeKdfComponent implements OnInit {
|
||||
kdfConfig: KdfConfig = DEFAULT_KDF_CONFIG;
|
||||
kdfType = KdfType;
|
||||
kdfOptions: any[] = [];
|
||||
recommendedPbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS;
|
||||
|
||||
// Default values for template
|
||||
protected PBKDF2_ITERATIONS = PBKDF2_ITERATIONS;
|
||||
protected ARGON2_ITERATIONS = ARGON2_ITERATIONS;
|
||||
protected ARGON2_MEMORY = ARGON2_MEMORY;
|
||||
protected ARGON2_PARALLELISM = ARGON2_PARALLELISM;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
@@ -42,12 +47,12 @@ export class ChangeKdfComponent implements OnInit {
|
||||
|
||||
async onChangeKdf(newValue: KdfType) {
|
||||
if (newValue === KdfType.PBKDF2_SHA256) {
|
||||
this.kdfConfig = new KdfConfig(DEFAULT_PBKDF2_ITERATIONS);
|
||||
this.kdfConfig = new KdfConfig(PBKDF2_ITERATIONS.defaultValue);
|
||||
} else if (newValue === KdfType.Argon2id) {
|
||||
this.kdfConfig = new KdfConfig(
|
||||
DEFAULT_ARGON2_ITERATIONS,
|
||||
DEFAULT_ARGON2_MEMORY,
|
||||
DEFAULT_ARGON2_PARALLELISM,
|
||||
ARGON2_ITERATIONS.defaultValue,
|
||||
ARGON2_MEMORY.defaultValue,
|
||||
ARGON2_PARALLELISM.defaultValue,
|
||||
);
|
||||
} else {
|
||||
throw new Error("Unknown KDF type.");
|
||||
|
||||
@@ -47,7 +47,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { DEFAULT_PBKDF2_ITERATIONS, KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { KdfType, PBKDF2_ITERATIONS } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
|
||||
@@ -967,7 +967,9 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
async isLowKdfIteration() {
|
||||
const kdfType = await this.stateService.getKdfType();
|
||||
const kdfOptions = await this.stateService.getKdfConfig();
|
||||
return kdfType === KdfType.PBKDF2_SHA256 && kdfOptions.iterations < DEFAULT_PBKDF2_ITERATIONS;
|
||||
return (
|
||||
kdfType === KdfType.PBKDF2_SHA256 && kdfOptions.iterations < PBKDF2_ITERATIONS.defaultValue
|
||||
);
|
||||
}
|
||||
|
||||
protected async repromptCipher(ciphers: CipherView[]) {
|
||||
|
||||
Reference in New Issue
Block a user