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