Pergunta

Qual a melhor forma de lidar com o gerenciamento de contas de usuários em um sistema, sem que seus funcionários que têm acesso a um banco de dados tenham acesso às contas.

Exemplos:

  1. Armazenando nome de usuário/senha no banco de dados.Esta é uma má ideia porque qualquer pessoa que tenha acesso a um banco de dados pode ver o nome de usuário e a senha.E, portanto, use-o.

  2. Armazenando hash de nome de usuário/senha.Este é um método melhor, mas a conta pode ser acessada substituindo o hash da senha no banco de dados pelo hash de outra conta cuja informação de autenticação você conhece.Então, após o acesso ser concedido, reverte-o de volta ao banco de dados.

Como o Windows/*nix lida com isso?

Foi útil?

Solução

Este era um problema comum no UNIX há muitos anos e foi resolvido separando os componentes de identidade do usuário (nome de usuário, UID, shell, nome completo, etc.) dos componentes de autenticação (hash de senha, hash salt de senha).Os componentes de identidade podem ser legíveis globalmente (e de fato devem ser, se os UIDs forem mapeados para nomes de usuário), mas os componentes de autenticação deve ser mantido inacessível aos usuários.Para autenticar um usuário, tenha um sistema confiável que aceite nome de usuário e senha e retorne um resultado simples de "autenticado" ou "não autenticado".Este sistema deve ser o único aplicativo com acesso ao banco de dados de autenticação e deve aguardar um período de tempo aleatório (talvez entre 0,1 e 3 segundos) antes de responder para ajudar a evitar ataques de temporização.

Outras dicas

Este é um método melhor, mas a conta pode ser acessada substituindo o hash da senha no banco de dados pelo hash de outra conta cuja informação de autenticação você conhece.

Não há realmente nenhuma maneira de contornar isso.Qualquer pessoa que tenha acesso de gravação ao arquivo de senha tem controle total do computador.

Eu escolheria 2, mas use um pouco de sal.Algum pseudocódigo:

SetPassword(user, password)
    salt = RandomString()
    hash = Hashfunction(salt+password)
    StoreInDatabase(user, salt, hash)

CheckPassword(user, password)
    (salt, hash) = GetFromDatabase(user)
    if Hashfunction(salt+password) == hash
        return "Success"
    else
        return "Login Failed"

É importante usar uma função hash bem conhecida (como MD5 ou SHA-1), implementada em uma biblioteca. Não crie o seu próprio nem tente implementá-lo a partir de um livro simplesmente não vale a pena correr o risco de errar.

@Brian R.Bondy:A razão pela qual você usa salt é para dificultar os ataques de dicionário, o invasor não pode fazer hash de um dicionário e tentar todas as senhas; em vez disso, ele precisa pegar o salt + o dicionário e fazer o hash, o que faz com que os requisitos de armazenamento sejam expostos.Se você tiver um dicionário com as 1000 senhas mais comuns e fizer hash, precisará de algo em torno de 16 kB, mas se adicionar duas letras aleatórias, obterá 62 * 62 * 16 kB ≈ 62 Mb.

Caso contrário, você poderia usar algum tipo de Senhas de uso único Ouvi coisas boas sobre o OTPW, mas não o usei.

Jeff Atwood tem alguns bons posts sobre hashing, se você decidir seguir esse caminho:

Você poderia usar o openID e não salvar nenhuma senha de usuário confidencial.Quem disse que é apenas para sites?

  1. Na verdade, uma péssima ideia.Se o banco de dados estiver comprometido, todas as contas serão comprometidas.
  2. Bom caminho a seguir.Se o seu algoritmo de hash incluir o nome de usuário, substituir o hash da senha por outro não funcionará.

O Unix armazena hashes em um arquivo de texto /etc/shadow, que é acessível apenas a usuários privilegiados.As senhas são criptografadas com sal.

Você poderia armazenar o sal para a senha com hash em outra tabela, é claro que cada usuário teria seu próprio salt.Você poderia então limitar o acesso a essa tabela.

A abordagem usual é usar a opção dois com email:

Armazene nome de usuário, hash de senha e endereço de e-mail no banco de dados.

O usuário pode inserir sua senha ou redefini-la, neste último caso é gerada uma senha aleatória, um novo hash é criado para o usuário e a senha é enviada a ele por e-mail.

Editar:Se o banco de dados estiver comprometido, você só poderá garantir que nenhuma informação sensível possa ser acessada; você não poderá mais garantir a segurança do seu aplicativo.

Hash o nome de usuário e a senha junto.Dessa forma, se dois usuários tiverem a mesma senha, os hashes ainda serão diferentes.

Isso não é um problema para muitos aplicativos porque obter acesso ao banco de dados é provavelmente o objetivo mais comum de qualquer invasor.Então, se eles já têm acesso ao banco de dados, por que ainda desejam fazer login no aplicativo?:)

Se o 'sistema' for um site público RPX pode fornecer serviços de login/conta de usuário para os provedores mais comuns, como OpenId, Facebook, Google, etc.

Agora, dada a maneira como você formula sua pergunta, acho que o 'sistema' do qual você está falando é mais provavelmente um aplicativo corporativo interno baseado em Windows/Linux.No entanto;para aqueles que procuram provedores de login/conta de usuário no Google (como eu fiz antes de encontrar o RPX), isso pode ser uma boa opção :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top