From 01091fe26081a0e59e517a245141227095724858 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 30 Jan 2023 15:07:51 +0100 Subject: [PATCH] [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 Co-authored-by: Kyle Spearrin --- apps/cli/src/commands/login.command.ts | 4 +- apps/cli/src/commands/unlock.command.ts | 4 +- .../components/reset-password.component.ts | 5 +- .../app/settings/change-email.component.ts | 4 +- .../app/settings/change-kdf.component.html | 107 +++++++++++++----- .../src/app/settings/change-kdf.component.ts | 79 +++++++++---- .../emergency-access-takeover.component.ts | 7 +- apps/web/src/app/vault/vault.component.ts | 8 +- apps/web/src/locales/en/messages.json | 15 ++- .../components/change-password.component.ts | 9 +- libs/angular/src/components/lock.component.ts | 22 +--- .../src/components/register.component.ts | 14 ++- .../src/components/set-password.component.ts | 14 ++- .../src/components/set-pin.component.ts | 4 +- .../components/update-password.component.ts | 2 +- .../update-temp-password.component.ts | 4 +- .../common/src/abstractions/crypto.service.ts | 7 +- .../responses/organization-user.response.ts | 4 + libs/common/src/abstractions/state.service.ts | 5 +- libs/common/src/enums/kdfType.ts | 9 +- .../bitwarden-password-protected-importer.ts | 3 +- .../misc/logInStrategies/logIn.strategy.ts | 2 + libs/common/src/models/domain/account.ts | 2 + libs/common/src/models/domain/kdf-config.ts | 11 ++ libs/common/src/models/request/kdf.request.ts | 2 + .../src/models/request/register.request.ts | 6 +- .../models/request/set-password.request.ts | 10 +- .../response/emergency-access.response.ts | 4 + .../response/identity-token.response.ts | 4 + .../src/models/response/prelogin.response.ts | 4 + libs/common/src/services/auth.service.ts | 11 +- libs/common/src/services/crypto.service.ts | 56 ++++++--- libs/common/src/services/export.service.ts | 7 +- .../src/services/keyConnector.service.ts | 5 +- libs/common/src/services/state.service.ts | 18 ++- 35 files changed, 329 insertions(+), 143 deletions(-) create mode 100644 libs/common/src/models/domain/kdf-config.ts diff --git a/apps/cli/src/commands/login.command.ts b/apps/cli/src/commands/login.command.ts index 6284f8b94b5..b6ec7f39590 100644 --- a/apps/cli/src/commands/login.command.ts +++ b/apps/cli/src/commands/login.command.ts @@ -410,7 +410,7 @@ export class LoginCommand { this.policyService.masterPasswordPolicyOptions$() ); const kdf = await this.stateService.getKdfType(); - const kdfIterations = await this.stateService.getKdfIterations(); + const kdfConfig = await this.stateService.getKdfConfig(); if ( enforcedPolicyOptions != null && @@ -431,7 +431,7 @@ export class LoginCommand { masterPassword, this.email.trim().toLowerCase(), kdf, - kdfIterations + kdfConfig ); const newPasswordHash = await this.cryptoService.hashPassword(masterPassword, newKey); diff --git a/apps/cli/src/commands/unlock.command.ts b/apps/cli/src/commands/unlock.command.ts index 7e2136e6e3e..28c892b58b4 100644 --- a/apps/cli/src/commands/unlock.command.ts +++ b/apps/cli/src/commands/unlock.command.ts @@ -44,8 +44,8 @@ export class UnlockCommand { await this.setNewSessionKey(); const email = await this.stateService.getEmail(); const kdf = await this.stateService.getKdfType(); - const kdfIterations = await this.stateService.getKdfIterations(); - const key = await this.cryptoService.makeKey(password, email, kdf, kdfIterations); + const kdfConfig = await this.stateService.getKdfConfig(); + const key = await this.cryptoService.makeKey(password, email, kdf, kdfConfig); const storedKeyHash = await this.cryptoService.getKeyHash(); let passwordValid = false; diff --git a/apps/web/src/app/organizations/members/components/reset-password.component.ts b/apps/web/src/app/organizations/members/components/reset-password.component.ts index 3d96426f707..391420c48a1 100644 --- a/apps/web/src/app/organizations/members/components/reset-password.component.ts +++ b/apps/web/src/app/organizations/members/components/reset-password.component.ts @@ -20,6 +20,7 @@ import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwo import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction"; 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"; @@ -156,6 +157,8 @@ export class ResetPasswordComponent implements OnInit, OnDestroy { const kdfType = response.kdf; const kdfIterations = response.kdfIterations; + const kdfMemory = response.kdfMemory; + const kdfParallelism = response.kdfParallelism; const resetPasswordKey = response.resetPasswordKey; const encryptedPrivateKey = response.encryptedPrivateKey; @@ -175,7 +178,7 @@ export class ResetPasswordComponent implements OnInit, OnDestroy { this.newPassword, this.email.trim().toLowerCase(), kdfType, - kdfIterations + new KdfConfig(kdfIterations, kdfMemory, kdfParallelism) ); const newPasswordHash = await this.cryptoService.hashPassword(this.newPassword, newKey); diff --git a/apps/web/src/app/settings/change-email.component.ts b/apps/web/src/app/settings/change-email.component.ts index 2c41bd0b78b..134698584ee 100644 --- a/apps/web/src/app/settings/change-email.component.ts +++ b/apps/web/src/app/settings/change-email.component.ts @@ -66,12 +66,12 @@ export class ChangeEmailComponent implements OnInit { request.newEmail = this.newEmail; request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null); const kdf = await this.stateService.getKdfType(); - const kdfIterations = await this.stateService.getKdfIterations(); + const kdfConfig = await this.stateService.getKdfConfig(); const newKey = await this.cryptoService.makeKey( this.masterPassword, this.newEmail, kdf, - kdfIterations + kdfConfig ); request.newMasterPasswordHash = await this.cryptoService.hashPassword( this.masterPassword, diff --git a/apps/web/src/app/settings/change-kdf.component.html b/apps/web/src/app/settings/change-kdf.component.html index 1b3b62a03fb..b01b83a954c 100644 --- a/apps/web/src/app/settings/change-kdf.component.html +++ b/apps/web/src/app/settings/change-kdf.component.html @@ -32,43 +32,94 @@ > - + + + +
- - - - - + + + + + + + + + + + + +
-
-
-

{{ "kdfIterationsDesc" | i18n: (recommendedKdfIterations | number) }}

- {{ "warning" | i18n }}: {{ "kdfIterationsWarning" | i18n: (50000 | number) }} -
-
+ +

+ {{ "kdfIterationsDesc" | i18n: (recommendedPbkdf2Iterations | number) }} +

+ + {{ "kdfIterationsWarning" | i18n: (100000 | number) }} + +
+ +

{{ "argon2Desc" | i18n }}

+ {{ "argon2Warning" | i18n }} +