private (string passwordToken, PasswordSalts passwordSalts, PasswordBasedBackup passwordBasedBackup) GeneratePasswordToken(string password, byte[] seed) { var passwordSalt = Scrypt.GenerateSalt(); var passwordHash = Scrypt.Hash(password, passwordSalt); //var passwordHkdfKey = crypto.hkdf.importHkdfKeyFromString(passwordHash) var passwordTokenSalt = Hkdf.GenerateSalt(); var passwordToken = Hkdf.GetPasswordToken(/*passwordHkdfKey*/ passwordHash, passwordTokenSalt); var passwordBasedEncryptionKeySalt = Hkdf.GenerateSalt(); var passwordBasedEncryptionKey = AesGcmUtils.GetPasswordBasedEncryptionKey(passwordHash, passwordBasedEncryptionKeySalt); var passwordEncryptedSeed = AesGcmUtils.Encrypt(passwordBasedEncryptionKey, seed); var passwordSalts = new PasswordSalts { PasswordSalt = Convert.ToBase64String(passwordSalt), PasswordTokenSalt = Convert.ToBase64String(passwordTokenSalt), }; var passwordBasedBackup = new PasswordBasedBackup { PasswordBasedEncryptionKeySalt = Convert.ToBase64String(passwordBasedEncryptionKeySalt), PasswordEncryptedSeed = Convert.ToBase64String(passwordEncryptedSeed), }; return(passwordToken, passwordSalts, passwordBasedBackup); }
public async Task <(string sessionId, DateTime creationDate, string userId)> GenerateKeysAndSignUp( string username, string password, byte[] seed, string email, Dictionary <string, string> profile) { var(passwordToken, passwordSalts, passwordBasedBackup) = GeneratePasswordToken(password, seed); var encryptionKeySalt = Hkdf.GenerateSalt(); var dhKeySalt = Hkdf.GenerateSalt(); var hmacKeySalt = Hkdf.GenerateSalt(); var dhPrivateKey = DiffieHellmanUtils.ImportKeyFromMaster(seed, dhKeySalt); var publicKey = DiffieHellmanUtils.GetPublicKey(dhPrivateKey); var keySalts = new KeySalts { EncryptionKeySalt = Convert.ToBase64String(encryptionKeySalt), DhKeySalt = Convert.ToBase64String(dhKeySalt), HmacKeySalt = Convert.ToBase64String(hmacKeySalt), }; var request = new SignUpApiRequest { Username = username, PasswordToken = passwordToken, PublicKey = publicKey, PasswordSalts = passwordSalts, KeySalts = keySalts, Email = email, Profile = profile, PasswordBasedBackup = passwordBasedBackup }; var response = await _api.SignUp(request); if (response.IsSuccessStatusCode) { var apiResponse = JsonConvert.DeserializeObject <SignUpApiResponse>(await response.Content.ReadAsStringAsync()); return(apiResponse.SessionId, apiResponse.CreationDate, apiResponse.UserId); } var one = ParseGenericErrors(await response.Content.ReadAsStringAsync(), response.StatusCode); if (one != null) { throw one; } var two = await ParseGenericUsernamePasswordError(response); if (two != null) { throw two; } throw new Exception($"Unknown error during SignUp: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); }