public void TestArgon2RoundTrip() { var password = "******"; byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[16]; Rng.GetBytes(salt); var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Password = passwordBytes, Salt = salt, TimeCost = 3, MemoryCost = 65536, Lanes = 4, Threads = 2, }; var argon2 = new Argon2(config); SecureArray <byte> hash = argon2.Hash(); var passwordHash = config.EncodeString(hash.Buffer); this.output.WriteLine($"Argon2 of {password} --> {passwordHash}"); Assert.True( Argon2.Verify(passwordHash, passwordBytes, SecureArray.DefaultCall), $"expected verify to work for {passwordHash} (Argon2 hash of {password}"); }
internal static void AddUser(string username, string password) { Argon2Config config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 3, MemoryCost = 32768, Lanes = 4, Threads = Environment.ProcessorCount, Password = Encoding.ASCII.GetBytes(password), Salt = Convert.FromBase64String(Properties.Settings.Default.Salt), // >= 8 bytes if not null HashLength = 20 // >= 4 }; Argon2 argon2 = new Argon2(config); string passwordHash; using (SecureArray <byte> hashA = argon2.Hash()) { passwordHash = config.EncodeString(hashA.Buffer); } var userCreated = new user() { username = username, passwordHash = passwordHash, isAdmin = false, isEnabled = false }; context.users.Add(userCreated); context.SaveChanges(); }
public async Task Post([FromBody] User user) { try { new MailAddress(user.Email); User users = await context.Users.Find(filter : new BsonDocument(Models.User.EMAILFIELD, user.Email)).FirstOrDefaultAsync(); if (users != null) { throw new Exception("User with such email exist."); } else { Argon2Config config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Salt = Encoding.Default.GetBytes(Resources.LocalSalt), Password = Encoding.Default.GetBytes(user.Password) }; user.HPass = Argon2.Hash(config); await context.Users.InsertOneAsync(user); new StatusCodeResult(StatusCodes.Status200OK); } } catch (Exception exception) { Response.StatusCode = StatusCodes.Status500InternalServerError; await HttpContext.Response.WriteAsync(exception.Message.ToString()); } }
public bool Verify(string username, string password) { string usernamePassword = $"{username}:{password}"; Argon2Config config = GetArgon2Config(usernamePassword); bool verified = Argon2.Verify(Configuration.AuthToken, config); return(verified); }
/// <summary> /// Compares a hash, salt and plain password and sets IsValid /// </summary> public SecuredPassword(string plainPassword, byte[] hash, byte[] salt, HashStrategyKind hashStrategy) { _hash = hash; _salt = salt; SetHashStrategy(hashStrategy); byte[] newKey; switch (hashStrategy) { case HashStrategyKind.Pbkdf210001Iterations: var numberOfIterations = (int)_hashingParameter; if (numberOfIterations <= 10000) { throw new ArgumentException("Iterations must be greater than 10000"); } using (var deriveBytes = new Rfc2898DeriveBytes(plainPassword, salt, numberOfIterations, HashAlgorithmName.SHA256)) { newKey = deriveBytes.GetBytes(_saltSize); IsValid = newKey.SequenceEqual(hash); } break; case HashStrategyKind.Argon2WorkCost: SecureArray <byte> hashB = null; try { var passwordBytes = Encoding.ASCII.GetBytes(plainPassword); var configOfPasswordToVerify = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 10, MemoryCost = (int)_hashingParameter, Lanes = 5, Threads = Environment.ProcessorCount, Salt = _salt, Password = passwordBytes, HashLength = 20 }; var hashString = Encoding.ASCII.GetString(_hash); if (configOfPasswordToVerify.DecodeString(hashString, out hashB) && hashB != null) { var argon2ToVerify = new Argon2(configOfPasswordToVerify); using (var hashToVerify = argon2ToVerify.Hash()) { if (!hashB.Buffer.Where((b, i) => b != hashToVerify[i]).Any()) { IsValid = true; } } } } finally { hashB?.Dispose(); } break; } }
private Argon2Config GetArgon2Config(string usernamePassword) { byte[] saltBytes = Encoding.UTF8.GetBytes(Configuration.AuthSalt); var config = new Argon2Config(); config.Password = Encoding.UTF8.GetBytes(usernamePassword); config.SecureArrayCall = null; config.Secret = saltBytes; config.Salt = saltBytes; config.MemoryCost = 10000; return(config); }
public static string Argon2Hash(string data) { Argon2Config config = DataHasher.Argon2Config; config.Password = Encoding.UTF8.GetBytes(data); byte[] salt = new byte[18]; RNG.GetBytes(salt); config.Salt = Encoding.UTF8.GetBytes(System.Convert.ToBase64String(salt)); using Argon2 argon2 = new Argon2(DataHasher.Argon2Config); using SecureArray <byte> hash = argon2.Hash(); return(DataHasher.Argon2Config.EncodeString(hash.Buffer)); }
/// <summary> /// Test <see cref="Argon2"/>. /// </summary> /// <returns> /// The result text. /// </returns> public static string TestArgon2RoundTrip() { var password = "******"; byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[16]; Rng.GetBytes(salt); var secret = "secret1"; byte[] secretBytes = Encoding.UTF8.GetBytes(secret); var failedResults = new List <string>(); var passedResults = new List <string>(); foreach (var argon2Type in new[] { Argon2Type.DataIndependentAddressing, Argon2Type.DataDependentAddressing, Argon2Type.HybridAddressing }) { var argon2Name = argon2Type == Argon2Type.DataIndependentAddressing ? "Argon2i" : argon2Type == Argon2Type.DataDependentAddressing ? "Argon2d" : "Argon2id"; var config = new Argon2Config { Type = argon2Type, Version = Argon2Version.Nineteen, Password = passwordBytes, Salt = salt, Secret = secretBytes, TimeCost = 3, MemoryCost = 65536, Lanes = 4, Threads = 2, }; var argon2 = new Argon2(config); SecureArray <byte> hash = argon2.Hash(); var passwordHash = config.EncodeString(hash.Buffer); Console.WriteLine($"{argon2Name} of {password} --> {passwordHash}"); if (Argon2.Verify(passwordHash, passwordBytes, secretBytes, SecureArray.DefaultCall)) { passedResults.Add(argon2Name); Console.WriteLine($"Round Trip {argon2Name} Passed"); } else { failedResults.Add(argon2Name); Console.WriteLine($"Round Trip {argon2Name} FAILED"); Console.WriteLine($" expected verify to work for {passwordHash} (Argon2 hash of {password})"); } } return(failedResults.Any() ? $"RoundTrip FAILED: [{string.Join(", ", failedResults)}] (passed: [{string.Join(", ", passedResults)}])" : "RoundTrip Passed"); }
/// <summary> /// Given a plain password and a hash strategy, calculate the salt and hash /// </summary> public SecuredPassword(string plainPassword, HashStrategyKind hashStrategy) { if (string.IsNullOrWhiteSpace(plainPassword)) { throw new ArgumentNullException(plainPassword); } SetHashStrategy(hashStrategy); switch (hashStrategy) { case HashStrategyKind.Pbkdf210001Iterations: var numberOfIterations = (int)_hashingParameter; if (numberOfIterations <= 10000) { throw new ArgumentException("Iterations must be greater than 10000"); } using (var deriveBytes = new Rfc2898DeriveBytes(plainPassword, _saltSize, numberOfIterations, HashAlgorithmName.SHA256)) { _salt = deriveBytes.Salt; _hash = deriveBytes.GetBytes(_saltSize); } break; case HashStrategyKind.Argon2WorkCost: byte[] passwordBytes = Encoding.UTF8.GetBytes(plainPassword); _salt = new byte[_saltSize]; RandomNumberGenerator.GetBytes(_salt); var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 10, MemoryCost = (int)_hashingParameter, Lanes = 5, Threads = Environment.ProcessorCount, Password = passwordBytes, Salt = _salt, HashLength = 20 }; var argon2A = new Argon2(config); using (SecureArray <byte> hashArgon = argon2A.Hash()) { _hash = Encoding.ASCII.GetBytes(config.EncodeString(hashArgon.Buffer)); } break; } IsValid = true; }
public Argon2IdHasherTests() { var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = _timeCost, MemoryCost = _memoryCost, Lanes = _lanes, Threads = Environment.ProcessorCount, Salt = Encoding.UTF8.GetBytes(_salt), HashLength = 20 }; _sut = new Argon2IdHasher(config); }
public void TestArgon2() { foreach (var testVector in Argon2TestVectors) { var encoded = new StringBuilder(); uint tagLength = (uint)testVector.TagLength; try { var config = new Argon2Config { Type = testVector.Type, Version = testVector.Version, TimeCost = testVector.Iterations, MemoryCost = testVector.MemoryKBytes, Lanes = testVector.Parallelism, Threads = testVector.Parallelism, Password = testVector.Password, Salt = testVector.Salt, Secret = testVector.Secret, AssociatedData = testVector.AssociatedData, HashLength = testVector.TagLength }; var argon2 = new Argon2(config); SecureArray <byte> hash = argon2.Hash(); Assert.False( hash.Buffer.Where((b, i) => b != testVector.Tag[i]).Any(), $"Test {testVector.Name}: Got{Environment.NewLine}{BitConverter.ToString(hash.Buffer)}{Environment.NewLine}expected{Environment.NewLine}{BitConverter.ToString(testVector.Tag)}"); this.output.WriteLine( "Passed Argon2:\r\n" + $" Version 0x{(int)testVector.Version:X} ({(int)testVector.Version})\r\n" + $" Type {testVector.Type}\r\n" + $" Iterations {testVector.Iterations}\r\n" + $" Memory KBytes {testVector.MemoryKBytes}\r\n" + $" Parallelism {testVector.Parallelism}\r\n" + $" Password {BitConverter.ToString(testVector.Password)}\r\n" + $" Salt {BitConverter.ToString(testVector.Salt)}\r\n" + $" Secret {BitConverter.ToString(testVector.Secret)}\r\n" + $" AssciatedData {BitConverter.ToString(testVector.AssociatedData)}\r\n" + $" Gave expected hash {BitConverter.ToString(hash.Buffer)}\r\n" + $" encoded {encoded}"); } catch (Exception e) { Assert.False(true, e.Message); } } }
public string HashPassword(string password, byte[] salt) { var passwordBytes = Encoding.UTF8.GetBytes(password); var argonConfig = new Argon2Config { Lanes = _lanes, Threads = _threads, Password = passwordBytes, Salt = salt, MemoryCost = _cost, }; using var argon = new Argon2(argonConfig); using var hash = argon.Hash(); return(argonConfig.EncodeString(hash.Buffer)); }
public IActionResult Register(AuthForm register) { _logger.LogInformation("Registration initiated"); var user = _userService.Get(register.UserName); if (user != null) { _logger.LogWarning("Duplicate user {User} found", register.UserName); return(Conflict(new { message = @"Username already exists" })); } var salt = Auth.GenerateSalt(); var argon2Config = new Argon2Config { Threads = Environment.ProcessorCount, Password = Encoding.UTF8.GetBytes(register.Password), Salt = salt, HashLength = 128 }; var hashedPassword = Argon2.Hash(argon2Config); var accessToken = Auth.GenerateJWToken(_config, register.UserName); var refreshToken = Auth.GenerateRefreshToken(_config, register.UserName); user = new User { UserName = register.UserName, Password = hashedPassword, Salt = salt, AccessToken = accessToken.Token, RefreshToken = refreshToken.Token, AccessExpiry = accessToken.Expiry }; _ = _userService.Add(user); return(Ok(new { accessToken = accessToken.Token, refreshToken = refreshToken.Token })); }
public IActionResult Login(AuthForm login) { _logger.LogInformation("Login initiated"); IActionResult response = Unauthorized(); var user = _userService.Get(login.UserName); if (user == null) { _logger.LogWarning("User {User} not found", login.UserName); return(response); } var argon2Config = new Argon2Config { Threads = Environment.ProcessorCount, Password = Encoding.UTF8.GetBytes(login.Password), Salt = user.Salt, HashLength = 128 }; if (Argon2.Verify(user.Password, argon2Config)) { _logger.LogInformation("User {User} logged in", login.UserName); var accessToken = Auth.GenerateJWToken(_config, user.UserName); var refreshToken = Auth.GenerateRefreshToken(_config, user.UserName); user.AccessToken = accessToken.Token; user.RefreshToken = refreshToken.Token; user.AccessExpiry = accessToken.Expiry; _userService.Update(user.Id, user); return(Ok(new { accessToken = accessToken.Token, refreshToken = refreshToken.Token })); } _logger.LogWarning("User {User} provided wrong password", login.UserName); return(response); }
public byte[] hash(byte[] associatedData, byte[] salt) { var config = new Argon2Config { Type = Argon2Type.HybridAddressing, Version = Argon2Version.Nineteen, TimeCost = timeCost, MemoryCost = memoryCost, Lanes = parallelism, Threads = Environment.ProcessorCount, Password = Utils.Combine(System.Text.Encoding.ASCII.GetBytes(salt.ToHex()), associatedData), Salt = System.Text.Encoding.ASCII.GetBytes(salt.ToHex()), // >= 8 bytes if not null HashLength = 32 // >= 4 }; var argon2A = new Argon2(config); Isopoh.Cryptography.SecureArray.SecureArray <byte> hashA = argon2A.Hash(); return(hashA.Buffer); }
/// <inheritdoc/> public override byte[] Hash(byte[] password, byte[] salt, int iterations) { var config = new Argon2Config { Type = (IArgon2.Argon2Type)Type, Version = (IArgon2.Argon2Version)Version, Password = password, Salt = salt, TimeCost = iterations, Lanes = Parallelism, Threads = Parallelism, HashLength = HashLength, MemoryCost = MemorySize * 1024, }; using var argon2 = new Argon2(config); using var result = argon2.Hash(); Debug.Assert(result.Buffer.Length == HashLength, "Unexpected hash length."); return((byte[])result.Buffer.Clone()); }
/// <summary> /// Test <see cref="Argon2"/>. /// </summary> /// <returns> /// The result text. /// </returns> public static string TestArgon2ThreadsDontMatter() { var password = "******"; byte[] passwordBytes = Encoding.UTF8.GetBytes(password); var configA = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Password = passwordBytes, TimeCost = 3, MemoryCost = 32, Lanes = 4, Threads = 3, }; var configB = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Password = passwordBytes, TimeCost = 3, MemoryCost = 32, Lanes = 4, Threads = 1, }; using (var argon2A = new Argon2(configA)) using (var argon2B = new Argon2(configB)) using (var hashA = argon2A.Hash()) using (var hashB = argon2B.Hash()) { var hashTextA = configA.EncodeString(hashA.Buffer); var hashTextB = configB.EncodeString(hashB.Buffer); var res = string.Compare(hashTextA, hashTextB, StringComparison.Ordinal) == 0 ? "ThreadsDontMatter Passed" : "ThreadsDontMatter FAILED"; Console.WriteLine(res); return(res); } }
public string HashPassword(string password) { if (string.IsNullOrEmpty(password)) { throw new ArgumentNullException(password); } byte[] salt = new byte[32]; Argon2Config argon2Config = _argon2Config; argon2Config.Password = Encoding.UTF8.GetBytes(password); argon2Config.Salt = salt; _randomNumberGenerator.GetBytes(salt); var argon2 = new Argon2(argon2Config); using SecureArray <byte> secureArray = argon2.Hash(); argon2.Dispose(); return(argon2Config.EncodeString(secureArray.Buffer)); }
public static byte[] Hash(byte[] input) { // // Summary: // Hashes the input using Dynamic's Argon2d parameters // Memory Cost = 500 // Lanes (degree of parallelism) = 8 // Time Cost = 2 // Threads = 1 (changing this parameter does not change the resulting hash but increasing slows it down) // Salt = input // Password = input // Hash length = 32 bytes // See https://github.com/duality-solutions/Dynamic/blob/master/src/hash.h // inline int Argon2d_Phase1_Hash() // Parameters: // input: // input bytes to hash. // // Returns: // The resulting hash byte array. // Argon2Config config = new Argon2Config(); config.MemoryCost = MEMORY_COST; config.Lanes = NUMBER_LANES; config.TimeCost = TIME_COST; config.Threads = NUMBER_THREADS; config.Salt = input; config.Password = input; config.HashLength = OUTPUT_BYTES; config.Type = Argon2Type.DataDependentAddressing; // DataDependentAddressing = Argon2d. DataIndependentAddressing = Argon2i. config.Version = Argon2Version.Nineteen; // not sure about this parameter. config.Secret = null; config.AssociatedData = null; string strHash = Argon2.Hash(config); return(Encoding.ASCII.GetBytes(strHash)); }
public static string EncryptPassword(string plainText, string salt) { byte[] passwordBytes = Encoding.UTF8.GetBytes(plainText); byte[] saltBytes = Encoding.UTF8.GetBytes(salt + "12345678"); var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 10, MemoryCost = 32768, Lanes = 5, Threads = Environment.ProcessorCount, Password = passwordBytes, Salt = saltBytes, // >= 8 bytes if not null HashLength = 20 // >= 4 }; var argon2A = new Argon2(config); using (SecureArray <byte> hashA = argon2A.Hash()) { return(config.EncodeString(hashA.Buffer)); } }
/// <summary> /// Given a password, salt and hash strategy, calculate the hash /// </summary> /// <param name="plainPassword"></param> /// <param name="salt"></param> /// <param name="hashStrategy"></param> public SecuredPassword(string plainPassword, byte[] salt, HashStrategyKind hashStrategy) { _salt = salt; SetHashStrategy(hashStrategy); switch (hashStrategy) { case HashStrategyKind.Pbkdf25009Iterations: case HashStrategyKind.Pbkdf28000Iterations: using (var deriveBytes = new Rfc2898DeriveBytes(plainPassword, salt, (int)_hashingParameter)) { _hash = deriveBytes.GetBytes(_saltSize); } break; case HashStrategyKind.Argon2WorkCost: byte[] passwordBytes = Encoding.UTF8.GetBytes(plainPassword); var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 10, MemoryCost = (int)_hashingParameter, Lanes = 5, Threads = Environment.ProcessorCount, Password = passwordBytes, Salt = _salt, HashLength = 20 // >= 4 }; var argon2A = new Argon2(config); using (SecureArray <byte> hashArgon = argon2A.Hash()) { _hash = Encoding.ASCII.GetBytes(config.EncodeString(hashArgon.Buffer)); } break; } IsValid = true; }
public void TestArgon2ThreadsDontMatter() { var password = "******"; byte[] passwordBytes = Encoding.UTF8.GetBytes(password); var configA = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Password = passwordBytes, TimeCost = 3, MemoryCost = 32, Lanes = 4, Threads = 3, }; var configB = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Password = passwordBytes, TimeCost = 3, MemoryCost = 32, Lanes = 4, Threads = 1, }; using (var argon2A = new Argon2(configA)) using (var argon2B = new Argon2(configB)) using (var hashA = argon2A.Hash()) using (var hashB = argon2B.Hash()) { var hashTextA = configA.EncodeString(hashA.Buffer); var hashTextB = configB.EncodeString(hashB.Buffer); Assert.Equal(hashTextA, hashTextB); } }
private string GetPasswordHash(string password) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[8]; RandomNumberGenerator Rng = RandomNumberGenerator.Create(); Rng.GetBytes(salt); var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, TimeCost = 5, MemoryCost = 16384, Password = passwordBytes, Salt = salt }; var argon2A = new Argon2(config); using (SecureArray <byte> hashA = argon2A.Hash()) { return(config.EncodeString(hashA.Buffer)); } }
/// <summary> /// Test <see cref="Argon2"/>. /// </summary> /// <returns> /// Result text. /// </returns> public static string TestArgon2() { var passed = true; var nl = Environment.NewLine; foreach (var testVector in Argon2TestVectors) { var encoded = new StringBuilder(); try { var config = new Argon2Config { Type = testVector.Type, Version = testVector.Version, TimeCost = testVector.Iterations, MemoryCost = testVector.MemoryKBytes, Lanes = testVector.Parallelism, Threads = testVector.Parallelism, Password = testVector.Password, Salt = testVector.Salt, Secret = testVector.Secret, AssociatedData = testVector.AssociatedData, HashLength = testVector.TagLength }; var argon2 = new Argon2(config); SecureArray <byte> hash = argon2.Hash(); if (!hash.Buffer.Where((b, i) => b != testVector.Tag[i]).Any()) { Console.WriteLine( $"Test {testVector.Name} passed:{nl}" + $" Version 0x{(int)testVector.Version:X} ({(int)testVector.Version}){nl}" + $" Type {testVector.Type}{nl}" + $" Iterations {testVector.Iterations}{nl}" + $" Memory KBytes {testVector.MemoryKBytes}{nl}" + $" Parallelism {testVector.Parallelism}{nl}" + $" Password {BitConverter.ToString(testVector.Password)}{nl}" + $" Salt {BitConverter.ToString(testVector.Salt)}{nl}" + $" Secret {BitConverter.ToString(testVector.Secret)}{nl}" + $" AssociatedData {BitConverter.ToString(testVector.AssociatedData)}{nl}" + $" Gave expected hash {BitConverter.ToString(hash.Buffer)}{nl}" + $" encoded {encoded}"); } else { Console.WriteLine( $"Test {testVector.Name}: Got{nl}" + $" {BitConverter.ToString(hash.Buffer)}{nl}" + $"expected{nl}" + $" {BitConverter.ToString(testVector.Tag)}"); passed = false; } } // ReSharper disable once CatchAllClause catch (Exception e) { Console.WriteLine($"Test {testVector.Name}: {e.Message} ({e.GetType()})"); } } var res = passed ? "Argon2 Passed" : "Argon2 FAILED"; Console.WriteLine(res); return(res); }
public static IServiceCollection AddArgon2IdHasher(this IServiceCollection services, Argon2Config config) { services.AddScoped <IArgon2IdHasher>((_) => new Argon2IdHasher(config)); return(services); }
public Argon2IdHasher(Argon2Config argon2Config) { _argon2Config = argon2Config; }
public async Task Get([FromQuery] string Email, [FromQuery] string Password) { try { User user = await context.Users.Find(filter : new BsonDocument(Models.User.EMAILFIELD, new BsonString(Email))).FirstOrDefaultAsync(); if (user == null) { throw new Exception("No User with such Email"); } Argon2Config config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, Salt = Encoding.Default.GetBytes(Resources.LocalSalt), Password = Encoding.Default.GetBytes(Password) }; string hPassword = Argon2.Hash(config); if (user.HPass.Equals(hPassword)) { var claims = new List <Claim> { new Claim(ClaimsIdentity.DefaultNameClaimType, user.Id.ToString()), new Claim(ClaimsIdentity.DefaultRoleClaimType, "User") }; ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); var now = DateTime.UtcNow; // создаем JWT-токен var jwt = new JwtSecurityToken( issuer: AuthOptions.ISSUER, audience: AuthOptions.AUDIENCE, notBefore: now, claims: claimsIdentity.Claims, expires: now.Add(TimeSpan.FromMinutes(AuthOptions.LIFETIME)), signingCredentials: new SigningCredentials(AuthOptions.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256)); var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); var response = new { access_token = encodedJwt, username = claimsIdentity.Name }; // сериализация ответа Response.ContentType = "application/json"; await Response.WriteAsync(JsonConvert.SerializeObject(response, new JsonSerializerSettings { Formatting = Formatting.Indented })); } else { throw new Exception("Wrong Password"); } } catch (Exception exception) { Response.StatusCode = StatusCodes.Status500InternalServerError; await HttpContext.Response.WriteAsync(exception.Message.ToString()); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSingleton(cfg => Configuration); #region Jwt var secretKey = Configuration["Jwt:Key"]; services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)), ValidateIssuer = false, ValidateAudience = false }; }); #endregion #region AutoMapper var autoMapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap <User, UserDTO>().ReverseMap(); cfg.CreateMap <CreateUserViewModel, UserDTO>().ReverseMap(); cfg.CreateMap <UpdateUserViewModel, UserDTO>().ReverseMap(); }); services.AddSingleton(autoMapperConfig.CreateMapper()); #endregion #region Database services.AddDbContext <ManagerContext>(options => options .UseSqlServer(Configuration["ConnectionStrings:ManagerAPISqlServer"]) .EnableSensitiveDataLogging() .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole())), ServiceLifetime.Transient); #endregion #region Repositories services.AddScoped <IUserRepository, UserRepository>(); #endregion #region Services services.AddScoped <IUserService, UserService>(); services.AddScoped <ITokenService, TokenService>(); #endregion #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Manager API", Version = "v1", Description = "API construída na serie de vídeos no canal Lucas Eschechola.", Contact = new OpenApiContact { Name = "Lucas Eschechola", Email = "*****@*****.**", Url = new Uri("https://eschechola.com.br") }, }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Por favor utilize Bearer <TOKEN>", Name = "Authorization", Type = SecuritySchemeType.ApiKey }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } }); }); #endregion #region Hash var config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = int.Parse(Configuration["Hash:TimeCost"]), MemoryCost = int.Parse(Configuration["Hash:MemoryCost"]), Lanes = int.Parse(Configuration["Hash:Lanes"]), Threads = Environment.ProcessorCount, Salt = Encoding.UTF8.GetBytes(Configuration["Hash:Salt"]), HashLength = int.Parse(Configuration["Hash:HashLength"]) }; services.AddArgon2IdHasher(config); #endregion #region Mediator services.AddMediatR(typeof(Startup)); services.AddScoped <INotificationHandler <DomainNotification>, DomainNotificationHandler>(); services.AddScoped <IMediatorHandler, MediatorHandler>(); #endregion }
internal static ObjectResult VerifyUser(string username, string password) { if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { return(new InvalidResult("Error: Username/Password are required.")); } try { var result = from user in context.users where user.username == username select user; if (result.Count() == 0) { return(new NotFoundResult("Error: User does not exist.")); } string passwordHash = result.First().passwordHash; bool? isAdmin = result.First().isAdmin; //START CODE BLOCK //-- Code within used from //https://github.com/mheyman/Isopoh.Cryptography.Argon2/blob/master/README.md Argon2Config config = new Argon2Config { Type = Argon2Type.DataIndependentAddressing, Version = Argon2Version.Nineteen, TimeCost = 3, MemoryCost = 32768, Lanes = 4, Threads = Environment.ProcessorCount, Password = Encoding.ASCII.GetBytes(password), Salt = Convert.FromBase64String(Properties.Settings.Default.Salt), HashLength = 20 }; SecureArray <byte> hashB = null; try { if (config.DecodeString(passwordHash, out hashB) && hashB != null) { var argon2ToVerify = new Argon2(config); using (var hashToVerify = argon2ToVerify.Hash()) { if (!hashB.Buffer.Where((b, i) => b != hashToVerify[i]).Any()) { return(new OkResult(isAdmin.ToString())); } else { return(new WrongResult("Error: Username/Password is incorrect.")); } } } } catch (Exception ex) { return(new InvalidResult("Error: Failed to verify password.")); } finally { hashB?.Dispose(); } //END CODE BLOCK } catch (Exception ex) { return(new InvalidResult("Error: Failed retrieving data from the database.")); } return(new InvalidResult("Error: Failed to process verification.")); }