//----------------------------------------------------------------------- // // Copyright (c) aliasvault. All rights reserved. // Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information. // //----------------------------------------------------------------------- namespace AliasVault.Cryptography.Client; using System.Text; using System.Text.Json; using Konscious.Security.Cryptography; /// /// Key derivation algorithms used for encryption/decryption. /// public static class Encryption { /// /// Derive a key used for encryption/decryption based on a user password and system salt. /// /// User password. /// The salt to use for the Argon2id hash. /// The encryption type to use. Defaults to . /// The encryption settings to use. Defaults to settings as defined in . /// Key derived from plain-text password as byte array. public static async Task DeriveKeyFromPasswordAsync(string password, string salt, string? encryptionType = null, string? encryptionSettings = null) { if (encryptionType is null) { encryptionType = Defaults.EncryptionType; } byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] saltBytes = Encoding.UTF8.GetBytes(salt); switch (encryptionType) { case "Argon2Id": return await Argon2Id(passwordBytes, saltBytes, encryptionSettings); default: throw new NotSupportedException($"Encryption type {encryptionType} is not supported."); } } /// /// Derive a key using Argon2id algorithm. /// /// Password bytes. /// Salt bytes. /// Encryption settings JSON string. /// Key derived from plain-text password as byte array. private static async Task Argon2Id(byte[] passwordBytes, byte[] saltBytes, string? encryptionSettings = null) { var degreeOfParallelism = Defaults.Argon2IdDegreeOfParallelism; var memorySize = Defaults.Argon2IdMemorySize; var iterations = Defaults.Argon2IdIterations; if (encryptionSettings is not null) { // Parse the encryption properties json string. var properties = JsonSerializer.Deserialize>(encryptionSettings); if (properties is not null) { if (properties.TryGetValue("DegreeOfParallelism", out int doP)) { degreeOfParallelism = doP; } if (properties.TryGetValue("MemorySize", out int memSize)) { memorySize = memSize; } if (properties.TryGetValue("Iterations", out int iter)) { iterations = iter; } } } var argon2 = new Argon2id(passwordBytes) { Salt = saltBytes, DegreeOfParallelism = degreeOfParallelism, MemorySize = memorySize, Iterations = iterations, }; return await argon2.GetBytesAsync(32); // Generate a 256-bit key } }