Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

pedradegelo

[Resolvido] proteção de senhas

Recommended Posts

Olá pessoal,

 

estou a criar um sistema de login e gostaria de saber como

proteger a senha. Eu vi na net que geralmente se transforma a

senha em uma chave através de códigos.

Então gostaria de saber quais sistemas para gerar essa chave

vocês recomendam.

 

Atenciosamente,

Cláudio

Compartilhar este post


Link para o post
Compartilhar em outros sites

apenas por curiosidade, poderia postar a estrutura da tabela onde está a senha ?

é algo importante

Compartilhar este post


Link para o post
Compartilhar em outros sites

Existem várias funções para criptografar.

 

Aconselho utilizar uma mistura delas, com ao menos 2 funções. Segue lista com links correspondentes:

 

md5() - http://br2.php.net/md5

sha1() - http://br2.php.net/manual/pt_BR/function.sha1.php

crc32() - http://br2.php.net/manual/pt_BR/function.crc32.php

crypt() - http://br2.php.net/manual/pt_BR/function.crypt.php -- Não aconselhável para senhas

base64_encode() - http://br2.php.net/manual/pt_BR/function.base64-encode.php

 

A função em negrito é a única que possui uma "contra-função", cuja decodifica o código gerado pela sua "oposta". Segue link:

 

base64_decode() - http://br2.php.net/manual/pt_BR/function.base64-decode.php

Como disse, é bom sempre usar uma mescla das funções, algo como:

 

sha1(md5("SENHA"));

// ou

md5(crc32("SENHA"));

Bom utilizar assim:

sha1(crc32(md5("SENHA")));

PS.: Se não estou enganado, a md5() já está praticamente obsoleta, visto que já foram comprovados vários ataques a sites que utilizavam apenas ela para proteger a senha, tanto brasileiros como gringos, certo? Então, se utilizá-la, sempre utilize uma segunda função para esconder o hash por ela gerado.

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

estou a criar um sistema de login e gostaria de saber como

proteger a senha. Eu vi na net que geralmente se transforma a

senha em uma chave através de códigos.

Então gostaria de saber quais sistemas para gerar essa chave

vocês recomendam.

 

Como o pessoal disse, existem várias funções de hash que tornam o armazenamento da senha mais seguro, eu pessoalmente gosto do DES e o MySQL implementa ele nativo (precisa de SSL)

 

Ola só:

mysql> create table `login` (
    ->   `id` mediumint(8) unsigned not null auto_increment,
    ->   `user` varchar(20) not null,
    ->   `pswd` blob not null,
    ->   primary key(`id`),
    ->   key `users`(`user`)
    -> ) engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)

Preste atenção no tipo da coluna pswd, ela é blob, isso porque vamos guardar nela dados sem nenhum tratamento (raw data):

 

mysql> insert into `login`( `user` , `pswd` ) values
    -> ( 'Neto' , des_encrypt( 'minhasenha' , 'Essa é a chave do seu sistema' ) ),
    -> ( 'Joao' , des_encrypt( 'outrasenha' , 'Essa é a chave do seu sistema' ) ),
    -> ( 'Mais' , des_encrypt( 'maissenha'  , 'Essa é a chave do seu sistema' ) );
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

Ok, inserimos 3 usuários, preste atenção que foi utilizado Essa é a chave do seu sistema, no lugar dessa frase você deve gerar uma mais difícil e o mais aleatória possível.

 

mysql> select * from `login`;
+----+------+-------------------+
| id | user | pswd              |
+----+------+-------------------+
|  1 | Neto | �=>����X&�?OV�� |
|  2 | Joao | �tI�=8IV"ט�=�%� |
|  3 | Mais | ��G���Z   8]�}v&�$> |
+----+------+-------------------+
3 rows in set (0.00 sec)

Como pode ver, os dados estão criptografados, agora fazendo um teste com uma chave errada:

 

mysql> select
    ->     `user`,
    ->     des_decrypt( `pswd` , 'Essa é a chave errada' )
    -> from
    ->     `login`
    -> where
    ->     `user` = 'Neto';
+------+--------------------------------------------------+
| user | des_decrypt( `pswd` , 'Essa é a chave errada' ) |
+------+--------------------------------------------------+
| Neto | NULL                                             |
+------+--------------------------------------------------+
1 row in set (0.00 sec)

Agora com a chave correta:

 

mysql> select
    ->     `user`,
    ->     des_decrypt( `pswd` , 'Essa é a chave do seu sistema' )
    -> from
    ->     `login`
    -> where
    ->     `user` = 'Neto';
+------+----------------------------------------------------------+
| user | des_decrypt( `pswd` , 'Essa é a chave do seu sistema' ) |
+------+----------------------------------------------------------+
| Neto | minhasenha                                               |
+------+----------------------------------------------------------+
1 row in set (0.00 sec)

Agora verificando acesso:

 

mysql> select
    ->   `user`,
    ->   des_decrypt( `pswd` , 'Essa é a chave ERRADA' ) 'pswd'
    -> from
    ->   `login`
    -> where
    ->   `user` = 'Neto'
    -> having
    ->   pswd = 'minhasenha';
Empty set (0.00 sec)

E com a chave correta:

 

mysql> select
    ->   `user`,
    ->   des_decrypt( `pswd` , 'Essa é a chave do seu sistema' ) 'pswd'
    -> from
    ->   `login`
    -> where
    ->   `user` = 'Neto'
    -> having
    ->   pswd = 'minhasenha';
+------+------------+
| user | pswd       |
+------+------------+
| Neto | minhasenha |
+------+------------+
1 row in set (0.00 sec)

O DES não é um algorítimo de criptografia dos mais seguros não, porém, dependendo da aplicação ele pode ser mais do que eficiente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

PS.: Se não estou enganado, a md5() já está praticamente obsoleta, visto que já foram comprovados vários ataques a sites que utilizavam apenas ela para proteger a senha, tanto brasileiros como gringos, certo? Então, se utilizá-la, sempre utilize uma segunda função para esconder o hash por ela gerado.

 

Para quebrar um hash, só com brute force. Logo, usar dois hashes dificulta, mas não inviabiliza a descoberta da senha. Isso depende da ignorância do criador da senha, ou seja, se ele coloca a senha "TsgdhyE3j7j12Nms" ou "abacaxi".

 

 

Um recurso importante de um sistema de autenticação é limitar o número de erros de senha, a fim de evitar ataques com brute force. Impessa o acesso após cinco erros de senha, por exemplo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para quebrar um hash, só com brute force. Logo, usar dois hashes dificulta, mas não inviabiliza a descoberta da senha. Isso depende da ignorância do criador da senha, ou seja, se ele coloca a senha "TsgdhyE3j7j12Nms" ou "abacaxi".

 

 

Um recurso importante de um sistema de autenticação é limitar o número de erros de senha, a fim de evitar ataques com brute force. Impessa o acesso após cinco erros de senha, por exemplo.

Estou com o Beraldo, o melhor a fazer, além de usar os 2 tipos de criptografia, seria mesmo limitando o número de tentativas para o login, seria bom também determinar um tamanho de caracteres para a senha, no máximo 10 dígitos. para impedir algum sql injection via campo.

 

Sim, Alaerte, mais não adianta, a pessoa pega o action do form e faz o campo sem limitação. Ótimo, então o que fazer ?!

 

if(strlen($_POST['campo']) > 10)
{
...
}

Sendo assim não tem como ultrapassar os 10 dígitos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu uso MD5 não vou postar aqui

por que vi varios link's que os amigos postaram

mesmo assim se você não conseguir me pede via MSN mesmo

jeimyson.almeida@hotmail.com

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá pessoal,

eu fiquei uns dias fora pois estava fazendo um concurso.

Até me assustei quanto a quantidade de respostas...rsrsrsrs

 

Primeiramente, muito obrigado a todos pelas respostas, em especial ao colega

João Batista Neto por descrever com muita paciência o seu método de uso.

 

Quanto ao que disse o colega ~TiuTalk~, acredito que colisão

seria a função gerar para 2 chaves diferentes o mesmo hash.

Portanto o melhor seria mesmo o 'sha1'.

 

Quanto ao que disse o colega Red FeniX, bem interessante o

método que ele utilizou: sha1(crc32(md5("SENHA")));

 

Quanto ao que disse o colega Alaerte Gabriel, muito bem

observado. Eu já havia lido um dizer muito interessante:

"nunca confie no usuário". Por isso a validação server

side ser muito interessante, uma vez que o form pode

vir de qualquer lugar, apenas com a action que interessa.

 

Agora quanto ao que disse o colega hinom, o que eu acredito

que seja estrutura da tabela 'users' segue (sempre respectivamente):

 

OBS: Existem outros campos ainda, porém acho que estes 3 são

os mais relevantes.

 

Field

-iduser

-email

-pass_2

Type

-int(10) unsigned

-varchar(80)

-varchar(x) -> x pq depende do numero de caracteres do hash: 32 para o md5 por ex.

Null

-No

-No

-No

Key

-PRI

-''

-''

Default

-NULL

-NULL

-NULL

Extra

-auto_increment

-''

-''

 

Perdão por qualquer equívoco cometido com os tipos de dados,

pois estou a iniciar agora no mysql.

Que você me diz, colega 'hinom'?

 

Abraços a todos

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo,

 

Li o tópico inteiro e o que você postou agora. Primeiramente fico feliz que você tenha entendido tudo que dissemos.

 

Agora, aconselho fazer uma função que junte tudo o que foi falado pelos amigos. Sua estrutura mysql tá normal, dentro do padrão. Porém, tenho uma ponderação:

 

Se você pretende fazer um portal que terá um grande fluxo de informação e, portanto, seja um alvo em potencial para invasões, você não deve confiar somente no método do João Batista, pois, como ele mesmo falou, o método ensinado não é tão seguro, ou ainda em um único método.

 

Se o seu projeto se encaixar no que falei anteriormente, aconselho que você use o que eu disse e junte com o que disse o Alaerte e o Beraldo. Você deve sempre limitar o número de caracteres da senha, verifique sempre se a senha não contém apenas o nome do usuário (ex.: user-iago / senha-iago) - essa verificação é bem tola, mas pode ajudar em alguns casos -, limite o número de tentativas de login(armazenando cada tentativa em session ou em uma variável) e utilize sempre duas ou mais criptografias diferentes.

 

Perceba que juntei tudo que foi falado e resumi nesse textinho ae.

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

é...como diria o engenheiro do Hamilton...

'Fantastic Job...great...great'

 

Grato ao colega Red Fenix.

E muito obrigado a todos que colaboraram.

 

Abraços,

Cláudio.

Compartilhar este post


Link para o post
Compartilhar em outros sites

vou explicar o motivo de ter pedido para postar a estrutura da tabela

em negrito, a coluna "email"

 

Agora quanto ao que disse o colega hinom, o que eu acredito

que seja estrutura da tabela 'users' segue (sempre respectivamente):

 

OBS: Existem outros campos ainda, porém acho que estes 3 são

os mais relevantes.

 

Field

-iduser

-email

-pass_2

Type

-int(10) unsigned

-varchar(80)

-varchar(x) -> x pq depende do numero de caracteres do hash: 32 para o md5 por ex.

Null

-No

-No

-No

Key

-PRI

-''

-''

Default

-NULL

-NULL

-NULL

Extra

-auto_increment

-''

-''

 

um dos motivos principais em encriptar a senha é evitar que uma pessoa com acesso direto ao banco saiba qual a senha de clientes por exemplo.

 

mas pense um pouco

 

99% dos sistemas oferecem recuperação de senha ou geração de nova senha baseado no email cadastrado

 

quem conseguir acessar o banco de dados e for um pouco esperto, trocará o endereço de email de um determinado cadastro para alguma utra conta pessoal.

com iso, basta requisitar a senha.

 

isso é um tipo de "falha".

entendeu ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa hinom,

 

Bem lembrado! O que ele pode fazer é criptografar o email também, não?

 

Tipo, nunca usei criptografia no e-mail, mas você tocou num ponto interessante que não havia pensado.

 

Qual sua sugestão pra resolver esse problema?

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

hinom, sei que não é muito legal ficar invadindo o tópico dos outros, mas nunca tinha pensado nisto também... O que você sugere neste caso?

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bem lembrado! O que ele pode fazer é criptografar o email também, não?

precisa ser codificado, obviamente com um codificador próprio com opção para decodificar, pois o email é um campo que precisa ser abstraído de qualquer forma.

 

não é 100% seguro, mas complica a vida de um invasor.

 

deve-se evitar a todo custo que tenham acesso ao fonte do sistema, ao decodificador, etc.

 

pode até ser um hash md5 mas desde que tenha uma chave para decodificá-lo.

 

unico inconveniente nesse caso é em sistemas onde precisa fazer pesquisa.

 

quando for procurar pelo campo email por exemplo, fazer uma listagemd e todos os emails que contenham "@foo.bar", o banco de dados não entenderá a codificação a menos que faça uma adaptação com algum plugin, procedure ou algo do gênero..

aí o buraco é mais embaixo

Compartilhar este post


Link para o post
Compartilhar em outros sites

hmm...puxa!!!

 

tem como criar a coluna email como somente leitura,

somente para receber dados?

 

 

editando:

saiu do escopo neh? kkkkkkkkkkk

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pode fazer algo um pouco mais complicado de gerenciar, porém, se torna mais seguro e resolve boa parte da questão da listagem e pesquisa por dados da coluna.

 

Ao gravar o endereço de email, separe o usuário e o domínio

 

 

Por exemplo

 

Na tabela principal do cadastro seria algo tipo

 

Nome
Email
EmailDomain

Nome: Foo bar
Email: info
EmailDomain: 55

 

55 seria o código para o dominio "foo.bar"

o email desse cadastrado seria info@foo.bar

 

Para referenciar, teria outra tabela somente para dominios

 

55 foo.bar

56 bar.foo

57 oof.rab

58...

 

nesse caso, bastaria codificar o código do dominio a coluna "EmailDomain"

 

ficaria algo do tipo

 

Nome: Foo bar
Email: info
EmailDomain: TYSgna25A
onde TYSgna25A representaria o numero 55

 

se o invasor for um pouco esperto desconfiará que o domain está codificado, mas poderá nao desconfiar de que se trata apenas de um código de referência, cuja codificação, para se tornar mais segura, pode ter algum tipo de chave publica e privada.

 

entendeu ?

é apenas uma sugestão simples e momentânea, pois existem N formas para se proteger eficientemente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.