English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Quem entende o sistema de autenticação MS Identity deve saber a função do UserManager, ele é o coordinador da estrutura inteira, ele define um conjunto de comportamentos de usuário para nos ajudar a gerenciar informações de usuário, informações de papel, lidar com senhas, etc. E sua implementação está no UserStore, podemos implementar o que ele define, como IUserStore, IUserPasswordStore, IRoleStore, etc. Podemos basear-nos em um conjunto completo de comportamentos de usuário, personalizar nossas informações de usuário e estrutura de dados e armazenamento de dados. Assim, sobre o Hasher de Senha, MS ainda nos fornece uma definição completa de comportamento, e é gerenciado pelo UserManager. Por exemplo
UserManager.PasswordHasher.HashPassword(password)
PasswordHasher é definido da seguinte maneira no interface UserManager:
Eu não estava interessado na implementação padrão original, então, por motivo de independentemente autenticar o login de várias aplicações, precisei de um projeto de autenticação de usuário independente como serviço de autenticação, que apenas gera tokens, e após a autenticação bem-sucedida, o usuário acessa os recursos de servidores de aplicações com o header de Authorization do HTTP Request levando o token.
Devido a essa razão, surgiu esse problema no autenticação de senha em várias aplicações:
Por exemplo, a aplicação A adotou a implementação de IPasswordHasher para personalizar o método de criptografia - MD5+Na forma de sal, enquanto a aplicação B adotou o PasswordHasher padrão do Identity para implementação, obtendo o seguinte código através da descompilação:
Portanto, para garantir a compatibilidade com diferentes métodos de criptografia de várias aplicações, tenho que descompilar o código-fonte, obter o método de criptografia padrão, determinar a criptografia ou descriptografia com base no nome da aplicação, ou diretamente comparar a senha inserida no banco de dados com a senha fornecida pelo usuário. Vamos ver a implementação específica do PasswordHasher padrão do MS.
// Descompilado com o decompiler do JetBrains // Tipo: Microsoft.AspNet.Identity.Crypto // Assembly: Microsoft.AspNet.Identity.Core, Versão=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // MVID: E3A10FFD-023A-4BC3-AD53-32D145ABF1C9 // Localização do assembly: C:\Sport\NovoProjeto\V2.0\Api\Fantasy.Sport\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll using System; using System.Runtime.CompilerServices; using System.Security.Cryptography; namespace Microsoft.AspNet.Identity { internal static class Crypto { private const int PBKDF2IterCount = 1000; private const int PBKDF2SubkeyLength = 32; private const int SaltSize = 16; public static string HashPassword(string password) { if (password == null) throw new ArgumentNullException("password"); byte[] salt; byte[] bytes; using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, 1000)) { salt = rfc2898DeriveBytes.Salt; bytes = rfc2898DeriveBytes.GetBytes(32); } byte[] inArray = new byte[49]); Buffer.BlockCopy((Array) salt, 0, (Array) inArray, 1, 16); Buffer.BlockCopy((Array) bytes, 0, (Array) inArray, 17, 32); return Convert.ToBase64String(inArray); } public static bool VerifyHashedPassword(string hashedPassword, string password) { if (hashedPassword == null) return false; if (password == null) throw new ArgumentNullException("password"); byte[] numArray = Convert.FromBase64String(hashedPassword); if (numArray.Length != 49 || (int) numArray[0] != 0) return false; byte[] salt = new byte[16]); Buffer.BlockCopy((Array) numArray, 1, (Array) salt, 0, 16); byte[] a = new byte[32]); Buffer.BlockCopy((Array) numArray, 17, (Array) a, 0, 32); byte[] bytes; using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, 1000)) bytes = rfc2898DeriveBytes.GetBytes(32); return Crypto.ByteArraysEqual(a, bytes); } [MethodImpl(MethodImplOptions.NoOptimization)] private static bool ByteArraysEqual(byte[] a, byte[] b) { if (object.ReferenceEquals((object) a, (object) b)) return true; if (a == null || b == null || a.Length != b.Length) return false; bool flag = true; for (int index = 0; index < a.Length; ++index) flag &= (int) a[index] == (int) b[index]; return flag; } } }
Alguém pode perguntar como aplicar esses códigos-fonte. Abaixo é uma breve descrição dessa questão.
No início, eu achei que era só uma criptografia, não precisava olhar com atenção, poderia usar diretamente?
Quando você registra um usuário e modifica uma senha, é feito a criptografia da senha através do método HashPassword acima. Portanto, quando eu comparo a senha de login do usuário no novo PasswordHasher personalizado, por que não criptografar a entrada do usuário diretamente com HashPassword? Portanto, o meu método VerifyHashedPassword (Verify traduzido como verificar) compara se o Pwd no banco de dados e o resultado processado pelo hasher são iguais. No entanto, o resultado é que, a cada vez que a string é a mesma, gera diferentes resultados de criptografia, e antes de jogar md5+A salt é diferente. Portanto, eu pensei na implementação padrão VerifyHashedPassword.
Portanto, o que temos para dizer por último é que você pode usar diretamente o método de criptografia do Microsoft Identity (o Hasher acima) para comparar a entrada do usuário com o resultado armazenado hashado no banco de dados, usando o método VerifyHashedPassword () ao comparar. Mesmo que você não use autenticação Identity, você também pode usar este algoritmo de criptografia
Isso é tudo o que há no artigo, espero que o conteúdo deste artigo ajude você a aprender ou a trabalhar, e também espero que você dê mais suporte ao tutorial Yell!
Declaração: O conteúdo deste artigo é extraído da internet, pertence ao autor original, o conteúdo é contribuído e carregado voluntariamente pelos usuários da internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade legal. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w3Declaração: O conteúdo deste artigo é extraído da internet, pertence ao autor original, o conteúdo é contribuído e carregado voluntariamente pelos usuários da internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade legal. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w