public async Task <IdentityResult> ChangeKdfAsync(User user, string masterPassword, string newMasterPassword, string key, KdfType kdf, int kdfIterations) { if (user == null) { throw new ArgumentNullException(nameof(user)); } if (await CheckPasswordAsync(user, masterPassword)) { var result = await UpdatePasswordHash(user, newMasterPassword); if (!result.Succeeded) { return(result); } user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow; user.Key = key; user.Kdf = kdf; user.KdfIterations = kdfIterations; await _userRepository.ReplaceAsync(user); await _pushService.PushLogOutAsync(user.Id); return(IdentityResult.Success); } Logger.LogWarning("Change KDF failed for user {userId}.", user.Id); return(IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch())); }
public SymmetricCryptoKey MakeKeyFromPassword(string password, string salt, KdfType kdf, int kdfIterations) { if (password == null) { throw new ArgumentNullException(nameof(password)); } if (salt == null) { throw new ArgumentNullException(nameof(salt)); } var passwordBytes = Encoding.UTF8.GetBytes(NormalizePassword(password)); var saltBytes = Encoding.UTF8.GetBytes(salt); byte[] keyBytes = null; if (kdf == KdfType.PBKDF2) { if (kdfIterations < 5000) { throw new Exception("PBKDF2 iteration minimum is 5000."); } keyBytes = _keyDerivationService.DeriveKey(passwordBytes, saltBytes, (uint)kdfIterations); } else { throw new Exception("Unknown Kdf."); } return(new SymmetricCryptoKey(keyBytes)); }
public static string WriteToFile(string fileDirectory, Wallet wallet, KdfType kdfType) { if (wallet?.KeyPairs == null || wallet.KeyPairs.Count != 1) { throw new NotSupportedException("This function expects a wallet with a single address"); } FileAttributes attributes = File.GetAttributes(fileDirectory); if (!attributes.HasFlag(FileAttributes.Directory)) { throw new InvalidOperationException("The provided path must be a directory"); } if (!Directory.Exists(fileDirectory)) { throw new InvalidOperationException("The provided directory path does not exist"); } var address = wallet.KeyPairs[0].PublicKey; var json = ExportToKeystore(kdfType, wallet, address, GetJsonSerializerSettings()); // UTC--2017-10-01T17-22-26.196Z--01caf1a3bf2164ec410b888c74d82a292c326487 var timestamp = $"{DateTimeOffset.UtcNow:s}".Replace(':', '-'); var lastDash = timestamp.LastIndexOf('-'); timestamp = timestamp.Remove(lastDash, 1); timestamp = timestamp.Insert(lastDash, "."); var filename = Path.Combine(fileDirectory, $"UTC--{timestamp}Z--{address.ToHex()}"); File.WriteAllText(filename, json); return(filename); }
public SetKeyConnectorKeyRequest(string key, KeysRequest keys, KdfType kdf, int?kdfIterations, string orgIdentifier) { this.Key = key; this.Keys = keys; this.Kdf = kdf; this.KdfIterations = kdfIterations; this.OrgIdentifier = orgIdentifier; }
public async Task SetInformationAsync(string userId, string email, KdfType kdf, int?kdfIterations) { _email = email; _userId = userId; _kdf = kdf; _kdfIterations = kdfIterations; await Task.WhenAll( _storageService.SaveAsync(Keys_UserEmail, email), _storageService.SaveAsync(Keys_UserId, userId), _storageService.SaveAsync(Keys_Kdf, (int)kdf), _storageService.SaveAsync(Keys_KdfIterations, kdfIterations)); }
public async Task <SymmetricCryptoKey> MakeKeyFromPinAsync(string pin, string salt, KdfType kdf, int kdfIterations) { var pinProtectedKey = await _storageService.GetAsync <string>(Constants.PinProtectedKey); if (pinProtectedKey == null) { throw new Exception("No PIN protected key found."); } var protectedKeyCs = new CipherString(pinProtectedKey); var pinKey = await MakePinKeyAysnc(pin, salt, kdf, kdfIterations); var decKey = await DecryptToBytesAsync(protectedKeyCs, pinKey); return(new SymmetricCryptoKey(decKey)); }
public async Task <SymmetricCryptoKey> MakePinKeyAysnc(string pin, string salt, KdfType kdf, int kdfIterations) { var pinKey = await MakeKeyAsync(pin, salt, kdf, kdfIterations); return(await StretchKeyAsync(pinKey)); }
public KeystoreFileStorageFormat(KdfType kdfType = KdfType.Scrypt) { _kdfType = kdfType; _jsonSettings = GetJsonSerializerSettings(); }
public static string ExportToKeystore(KdfType kdfType, Wallet wallet, byte[] address, JsonSerializerSettings jsonSettings) { Contract.Assert(!string.IsNullOrWhiteSpace(wallet.PasswordHash)); var passwordHashBytes = Encoding.UTF8.GetBytes(wallet.PasswordHash); var salt = CryptoUtil.RandomBytes(32); var kdfparams = new { dklen = 32, salt = salt.ToHex() }; byte[] derivedKey; switch (kdfType) { case KdfType.Scrypt: { derivedKey = PasswordHash.ScryptHashBinary(passwordHashBytes, salt, PasswordHash.Strength.Sensitive, kdfparams.dklen); break; } case KdfType.Argon: { derivedKey = PasswordHash.ArgonHashBinary(passwordHashBytes, salt, PasswordHash.StrengthArgon.Sensitive, kdfparams.dklen); break; } default: throw new NotSupportedException("Unsupported kdf"); } var iv = CryptoUtil.RandomBytes(32); var pKey = wallet.GetPrivateKeyByAddress(address); var nonce = derivedKey.Take(24).ToArray(); var box = SecretBox.CreateDetached(pKey, nonce, iv); var keystore = new Keystore { Version = KeystoreVersion, Id = wallet.Id, Address = address.ToHex(), Crypto = new KeystoreCrypto { CipherText = box.CipherText.ToHex(), CipherParameters = new KeystoreCryptoParameters { Iv = iv.ToHex() }, Cipher = "crypto_secretbox_detached", Kdf = kdfType.ToString().ToLowerInvariant(), KdfParameters = new KeystoreKdfParameters { Salt = kdfparams.salt, DerivedKeyLength = kdfparams.dklen, }, Mac = box.Mac.ToHex() } }; return(JsonConvert.SerializeObject(keystore, Formatting.None, jsonSettings)); }