mirror of
https://github.com/bitwarden/mobile
synced 2025-12-20 02:03:49 +00:00
[PM-2713] rename password hash to master key hash
This commit is contained in:
@@ -319,20 +319,20 @@ namespace Bit.App.Pages
|
||||
else
|
||||
{
|
||||
var masterKey = await _cryptoService.MakeMasterKeyAsync(MasterPassword, _email, kdfConfig);
|
||||
var storedKeyHash = await _cryptoService.GetPasswordHashAsync();
|
||||
var storedKeyHash = await _cryptoService.GetMasterKeyHashAsync();
|
||||
var passwordValid = false;
|
||||
MasterPasswordPolicyOptions enforcedMasterPasswordOptions = null;
|
||||
|
||||
if (storedKeyHash != null)
|
||||
{
|
||||
// Offline unlock possible
|
||||
passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(MasterPassword, masterKey);
|
||||
passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(MasterPassword, masterKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Online unlock required
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
|
||||
var keyHash = await _cryptoService.HashPasswordAsync(MasterPassword, masterKey, HashPurpose.ServerAuthorization);
|
||||
var keyHash = await _cryptoService.HashMasterKeyAsync(MasterPassword, masterKey, HashPurpose.ServerAuthorization);
|
||||
var request = new PasswordVerificationRequest();
|
||||
request.MasterPasswordHash = keyHash;
|
||||
|
||||
@@ -341,8 +341,8 @@ namespace Bit.App.Pages
|
||||
var response = await _apiService.PostAccountVerifyPasswordAsync(request);
|
||||
enforcedMasterPasswordOptions = response.MasterPasswordPolicy;
|
||||
passwordValid = true;
|
||||
var localKeyHash = await _cryptoService.HashPasswordAsync(MasterPassword, masterKey, HashPurpose.LocalAuthorization);
|
||||
await _cryptoService.SetPasswordHashAsync(localKeyHash);
|
||||
var localKeyHash = await _cryptoService.HashMasterKeyAsync(MasterPassword, masterKey, HashPurpose.LocalAuthorization);
|
||||
await _cryptoService.SetMasterKeyHashAsync(localKeyHash);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace Bit.App.Pages
|
||||
newMasterKey,
|
||||
await _cryptoService.MakeUserKeyAsync()
|
||||
);
|
||||
var hashedPassword = await _cryptoService.HashPasswordAsync(MasterPassword, newMasterKey);
|
||||
var hashedPassword = await _cryptoService.HashMasterKeyAsync(MasterPassword, newMasterKey);
|
||||
var (newPublicKey, newProtectedPrivateKey) = await _cryptoService.MakeKeyPairAsync(newUserKey);
|
||||
var request = new RegisterRequest
|
||||
{
|
||||
|
||||
@@ -166,8 +166,8 @@ namespace Bit.App.Pages
|
||||
var kdfConfig = new KdfConfig(KdfType.PBKDF2_SHA256, Constants.Pbkdf2Iterations, null, null);
|
||||
var email = await _stateService.GetEmailAsync();
|
||||
var newMasterKey = await _cryptoService.MakeMasterKeyAsync(MasterPassword, email, kdfConfig);
|
||||
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, newMasterKey, HashPurpose.ServerAuthorization);
|
||||
var localMasterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, newMasterKey, HashPurpose.LocalAuthorization);
|
||||
var masterPasswordHash = await _cryptoService.HashMasterKeyAsync(MasterPassword, newMasterKey, HashPurpose.ServerAuthorization);
|
||||
var localMasterPasswordHash = await _cryptoService.HashMasterKeyAsync(MasterPassword, newMasterKey, HashPurpose.LocalAuthorization);
|
||||
|
||||
var (newUserKey, newProtectedUserKey) = await _cryptoService.EncryptUserKeyWithMasterKeyAsync(newMasterKey,
|
||||
await _cryptoService.GetUserKeyAsync() ?? await _cryptoService.MakeUserKeyAsync());
|
||||
@@ -197,7 +197,7 @@ namespace Bit.App.Pages
|
||||
await _apiService.SetPasswordAsync(request);
|
||||
await _stateService.SetKdfConfigurationAsync(kdfConfig);
|
||||
await _cryptoService.SetMasterKeyAsync(newMasterKey);
|
||||
await _cryptoService.SetPasswordHashAsync(localMasterPasswordHash);
|
||||
await _cryptoService.SetMasterKeyHashAsync(localMasterPasswordHash);
|
||||
await _cryptoService.SetMasterKeyEncryptedUserKeyAsync(newProtectedUserKey.EncryptedString);
|
||||
await _cryptoService.SetPrivateKeyAsync(keys.Item2.EncryptedString);
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Bit.App.Pages
|
||||
|
||||
// Create new master key and hash new password
|
||||
var masterKey = await _cryptoService.MakeMasterKeyAsync(MasterPassword, email, kdfConfig);
|
||||
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, masterKey);
|
||||
var masterPasswordHash = await _cryptoService.HashMasterKeyAsync(MasterPassword, masterKey);
|
||||
|
||||
// Encrypt user key with new master key
|
||||
var (userKey, newProtectedUserKey) = await _cryptoService.EncryptUserKeyWithMasterKeyAsync(masterKey);
|
||||
@@ -155,7 +155,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task UpdatePasswordAsync(string newMasterPasswordHash, string newEncKey)
|
||||
{
|
||||
var currentPasswordHash = await _cryptoService.HashPasswordAsync(CurrentMasterPassword, null);
|
||||
var currentPasswordHash = await _cryptoService.HashMasterKeyAsync(CurrentMasterPassword, null);
|
||||
|
||||
var request = new PasswordRequest
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Bit.App.Services
|
||||
return false;
|
||||
};
|
||||
|
||||
return await _cryptoService.CompareAndUpdatePasswordHashAsync(password, null);
|
||||
return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null);
|
||||
}
|
||||
|
||||
public async Task<bool> Enabled()
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Bit.App.Utilities
|
||||
}
|
||||
|
||||
var parameters = GetParameters();
|
||||
parameters.Secret = await _cryptoService.HashPasswordAsync(password, null);
|
||||
parameters.Secret = await _cryptoService.HashMasterKeyAsync(password, null);
|
||||
parameters.VerificationType = VerificationType.MasterPassword;
|
||||
await ExecuteAsync(parameters);
|
||||
break;
|
||||
|
||||
@@ -27,11 +27,11 @@ namespace Bit.Core.Abstractions
|
||||
Task<UserKey> DecryptUserKeyWithMasterKeyAsync(MasterKey masterKey, EncString encUserKey = null, string userId = null);
|
||||
Task<Tuple<SymmetricCryptoKey, EncString>> MakeDataEncKeyAsync(UserKey key);
|
||||
Task<Tuple<SymmetricCryptoKey, EncString>> MakeDataEncKeyAsync(OrgKey key);
|
||||
Task<string> HashPasswordAsync(string password, SymmetricCryptoKey key, HashPurpose hashPurpose = HashPurpose.ServerAuthorization);
|
||||
Task SetPasswordHashAsync(string keyHash);
|
||||
Task<string> GetPasswordHashAsync();
|
||||
Task ClearPasswordHashAsync(string userId = null);
|
||||
Task<bool> CompareAndUpdatePasswordHashAsync(string masterPassword, MasterKey key);
|
||||
Task<string> HashMasterKeyAsync(string password, MasterKey key, HashPurpose hashPurpose = HashPurpose.ServerAuthorization);
|
||||
Task SetMasterKeyHashAsync(string keyHash);
|
||||
Task<string> GetMasterKeyHashAsync();
|
||||
Task ClearMasterKeyHashAsync(string userId = null);
|
||||
Task<bool> CompareAndUpdateKeyHashAsync(string masterPassword, MasterKey key);
|
||||
Task SetOrgKeysAsync(IEnumerable<ProfileOrganizationResponse> orgs);
|
||||
Task<OrgKey> GetOrgKeyAsync(string orgId);
|
||||
Task<Dictionary<string, OrgKey>> GetOrgKeysAsync();
|
||||
|
||||
@@ -145,8 +145,8 @@ namespace Bit.Core.Services
|
||||
SelectedTwoFactorProviderType = null;
|
||||
_2faForcePasswordResetReason = null;
|
||||
var key = await MakePreloginKeyAsync(masterPassword, email);
|
||||
var hashedPassword = await _cryptoService.HashPasswordAsync(masterPassword, key);
|
||||
var localHashedPassword = await _cryptoService.HashPasswordAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
var hashedPassword = await _cryptoService.HashMasterKeyAsync(masterPassword, key);
|
||||
var localHashedPassword = await _cryptoService.HashMasterKeyAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
var result = await LogInHelperAsync(email, hashedPassword, localHashedPassword, null, null, null, key, null, null, null, captchaToken);
|
||||
|
||||
if (await RequirePasswordChangeAsync(email, masterPassword))
|
||||
@@ -236,8 +236,8 @@ namespace Bit.Core.Services
|
||||
{
|
||||
SelectedTwoFactorProviderType = null;
|
||||
var key = await MakePreloginKeyAsync(masterPassword, email);
|
||||
var hashedPassword = await _cryptoService.HashPasswordAsync(masterPassword, key);
|
||||
var localHashedPassword = await _cryptoService.HashPasswordAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
var hashedPassword = await _cryptoService.HashMasterKeyAsync(masterPassword, key);
|
||||
var localHashedPassword = await _cryptoService.HashMasterKeyAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
return await LogInHelperAsync(email, hashedPassword, localHashedPassword, null, null, null, key, twoFactorProvider,
|
||||
twoFactorToken, remember);
|
||||
}
|
||||
@@ -473,7 +473,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (localHashedPassword != null)
|
||||
{
|
||||
await _cryptoService.SetPasswordHashAsync(localHashedPassword);
|
||||
await _cryptoService.SetMasterKeyHashAsync(localHashedPassword);
|
||||
}
|
||||
|
||||
if (code == null || tokenResponse.Key != null)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Bit.Core.Services
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
|
||||
private SymmetricCryptoKey _legacyEtmKey;
|
||||
private string _passwordHash;
|
||||
private string _masterKeyHash;
|
||||
private byte[] _publicKey;
|
||||
private byte[] _privateKey;
|
||||
private Dictionary<string, OrgKey> _orgKeys;
|
||||
@@ -37,7 +37,7 @@ namespace Bit.Core.Services
|
||||
public void ClearCache()
|
||||
{
|
||||
_legacyEtmKey = null;
|
||||
_passwordHash = null;
|
||||
_masterKeyHash = null;
|
||||
_publicKey = null;
|
||||
_privateKey = null;
|
||||
_orgKeys = null;
|
||||
@@ -211,64 +211,62 @@ namespace Bit.Core.Services
|
||||
return await BuildProtectedSymmetricKey<SymmetricCryptoKey>(key, newSymKey);
|
||||
}
|
||||
|
||||
// TODO(Jake): Uses Master Key
|
||||
public async Task<string> HashPasswordAsync(string password, SymmetricCryptoKey key, HashPurpose hashPurpose = HashPurpose.ServerAuthorization)
|
||||
public async Task<string> HashMasterKeyAsync(string password, MasterKey masterKey, HashPurpose hashPurpose = HashPurpose.ServerAuthorization)
|
||||
{
|
||||
if (key == null)
|
||||
if (masterKey == null)
|
||||
{
|
||||
key = await GetMasterKeyAsync();
|
||||
masterKey = await GetMasterKeyAsync();
|
||||
}
|
||||
if (password == null || key == null)
|
||||
if (password == null || masterKey == null)
|
||||
{
|
||||
throw new Exception("Invalid parameters.");
|
||||
}
|
||||
var iterations = hashPurpose == HashPurpose.LocalAuthorization ? 2 : 1;
|
||||
var hash = await _cryptoFunctionService.Pbkdf2Async(key.Key, password, CryptoHashAlgorithm.Sha256, iterations);
|
||||
var hash = await _cryptoFunctionService.Pbkdf2Async(masterKey.Key, password, CryptoHashAlgorithm.Sha256, iterations);
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
|
||||
public Task SetPasswordHashAsync(string keyHash)
|
||||
public Task SetMasterKeyHashAsync(string keyHash)
|
||||
{
|
||||
_passwordHash = keyHash;
|
||||
_masterKeyHash = keyHash;
|
||||
return _stateService.SetKeyHashAsync(keyHash);
|
||||
}
|
||||
|
||||
public async Task<string> GetPasswordHashAsync()
|
||||
public async Task<string> GetMasterKeyHashAsync()
|
||||
{
|
||||
if (_passwordHash != null)
|
||||
if (_masterKeyHash != null)
|
||||
{
|
||||
return _passwordHash;
|
||||
return _masterKeyHash;
|
||||
}
|
||||
var passwordHash = await _stateService.GetKeyHashAsync();
|
||||
if (passwordHash != null)
|
||||
{
|
||||
_passwordHash = passwordHash;
|
||||
_masterKeyHash = passwordHash;
|
||||
}
|
||||
return _passwordHash;
|
||||
return _masterKeyHash;
|
||||
}
|
||||
|
||||
public Task ClearPasswordHashAsync(string userId = null)
|
||||
public Task ClearMasterKeyHashAsync(string userId = null)
|
||||
{
|
||||
_passwordHash = null;
|
||||
_masterKeyHash = null;
|
||||
return _stateService.SetKeyHashAsync(null, userId);
|
||||
}
|
||||
|
||||
// TODO(Jake): Uses Master Key
|
||||
public async Task<bool> CompareAndUpdatePasswordHashAsync(string masterPassword, MasterKey key)
|
||||
public async Task<bool> CompareAndUpdateKeyHashAsync(string masterPassword, MasterKey key)
|
||||
{
|
||||
var storedPasswordHash = await GetPasswordHashAsync();
|
||||
var storedPasswordHash = await GetMasterKeyHashAsync();
|
||||
if (masterPassword != null && storedPasswordHash != null)
|
||||
{
|
||||
var localPasswordHash = await HashPasswordAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
var localPasswordHash = await HashMasterKeyAsync(masterPassword, key, HashPurpose.LocalAuthorization);
|
||||
if (localPasswordHash != null && storedPasswordHash == localPasswordHash)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var serverPasswordHash = await HashPasswordAsync(masterPassword, key, HashPurpose.ServerAuthorization);
|
||||
var serverPasswordHash = await HashMasterKeyAsync(masterPassword, key, HashPurpose.ServerAuthorization);
|
||||
if (serverPasswordHash != null & storedPasswordHash == serverPasswordHash)
|
||||
{
|
||||
await SetPasswordHashAsync(localPasswordHash);
|
||||
await SetMasterKeyHashAsync(localPasswordHash);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
var passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(secret, null);
|
||||
var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(secret, null);
|
||||
if (!passwordValid)
|
||||
{
|
||||
await InvalidSecretErrorAsync(verificationType);
|
||||
|
||||
Reference in New Issue
Block a user