Sessao de usuario

Pessoal,

para eu validar a conta de um usuario e senha em uma aplicacao desktop, usando um banco de dados SQL, é preciso fazer um select simples pedindo para verificar se o nome e a senha são iguais ou como devo fazer ??

valew pessoas

Você teve o azar de postar esta dúvida em um site onde tem uns caras bitolados em segurança, como eu.

Normalmente você faria algo como

select senha from usuarios where usuario = "jose"

ou algo como

select count (*) from usuarios where usuario = "jose" and senha = "senhasecreta"

e compararia no seu programa. Não faça isso, se puder. Não assuma a responsabilidade de guardar senhas, se possível - mesmo senhas criptografadas.

Daqui a pouco explico direitinho.

Você pode guardar o hash da senha, em vez da própria senha. Vou dar um exemplo.

import java.security.*;

public class PasswordMD5 {
	public static void main(String[] args) {
		try {
		    String password = PasswordMD5.toPassword ("NicoleKidman"); // a senha cadastrada
		    System.out.println ("password = " + password);
		    String password2 = PasswordMD5.toPassword ("NicoleKIdman"); // usuário digitou errado
		    System.out.println ("password2 = " + password2);
		    String password3 = PasswordMD5.toPassword ("NicoleKidman"); // usuário digitou certo
		    System.out.println ("password3 = " + password3); 
		    if (!password.equals(password2)) {
		        // como a senha não bate...
		        System.out.println ("password2 eh uma senha incorreta"); 
                    }
		    if (password.equals(password3)) {
		        // como a senha bate...
		        System.out.println ("password3 eh uma senha correta"); 
                    }
		} catch (Exception ex) {
		    ex.printStackTrace();
		}
        }
	private static String bytesToHex (byte[] b) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < b.length; ++i) {
			sb.append ((Integer.toHexString((b[i] & 0xFF) | 0x100)).substring(1,3));
		}
		return sb.toString();
	}
	public static String toPassword (String data) throws NoSuchAlgorithmException {
		byte[] mybytes = data.getBytes();
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		byte[] md5digest = md5.digest (mybytes);
		return bytesToHex (md5digest);
	}
}

O que você tem de fazer:

  • Definir um campo na sua tabela com 32 caracteres (que é o hash da senha). Esse campo tem comprimento fixo - o hash tem sempre o mesmo tamanho para qualquer senha.
  • Se a senha for esquecida, você tem de ter uma funcionalidade no seu sistema para reinicializar a senha. É que a senha não pode ser recuperada por ninguém, nem por você mesmo, porque não dá para obter a senha a partir do hash, embora você possa obter o hash a partir da senha.
  • Para saber se a senha está correta, calcule o hash da senha dada pelo usuário e compare com o hash gravado no banco. Se baterem, muito provavelmente a senha está correta. (Eu digo “muito provavelmente” porque há uma probabilidade infinitesimal de que haja duas senhas com o mesmo hash.)

thingol,

acho que vc foi o cara que mais clareou minhas ideias com relacao a isso, so uma duvida ou mais uma parte que nao ficou bem clara, o campo do meu banco de dados eu devo determinar um numero minimo de caracteres, pois 32 seria bastante coisa, mas com um nivel de quebra de senha muito mais dificultada.

Valew pela sua dica

Quanto a efetuar “crítica da senha” são outros quinhentos. Isso é você que deve fazer. Porque é que eu disse que você tem de deixar 32 caracteres para o campo de hash no seu banco de dados? É que essa função sempre retorna 32 caracteres - sendo a senha fraca, como “a”, ou forte, como “g8d+L0fuLK6Aa5JjNYD6LyUOZ/6a9ivtY0es3Wq/”.

Senha -> Hash
angelinajolie -> 9e99a57b8facab09d87551f98298cd38
a -> 0cc175b9c0f1b6a831c399e269772661
g8d+L0fuLK6Aa5JjNYD6LyUOZ/6a9ivtY0es3Wq/ -> 4d8bacbfe824e1a7223b6dee0aa6919c

Thingol, vc não quer escrever uma classe genérica de criptografia para por no brazilutils não? :mrgreen:

Boa idéia.
Só saber que tipos de coisas são necessárias:

  • Validação de senhas (que é a receita de bolo que passei aqui)
  • ?

Existe uma coisa muito específica para o Brasil, que é efetuar a análise de um certificado X.509 emitido por uma autoridade certificadora integrante do ICP-Brasil ( para mais detalhes veja http://www.iti.br ). A autoridade certificadora mais conhecida é a Receita Federal, que emite o CNPJ e CPF eletrônico (em smartcard).
Com um certificado desses, é possível obter o CPF, CNPJ etc. do detentor do certificado - isso requer a biblioteca BouncyCastle (que não é muito pequena e fica mudando a cada versão) e não deveria ser posto com o jar principal do BrazilUtils, já que requer essa dependência.

Thingol, a receita de bolo é fundamental.
Mas quanto a utilizar a biblioteca bouncycastle(jah baixei aqui, mas nunca usei), realmente é grande.Mas se botarmos que a API requere uma dependência externa para usar essa feature eu acho q ninguém chiaria…

Poderia ser criado um jar do tipo “basic” e outro “Enterprise”???
Bom, se vc quiser implementar, crie uma pack tipo brazilutils.security (ou algo + ou - assim) que nós(membros do projeto e desenvolvedores em geral), ficaremos muuuuito gratos.Não se esqueça de criar um TestCase testando o q vc fez!

Acho que é boa essa idéia de separar o jar do BrazilUtils - é besteira ter de instalar o provider BouncyCastle (é mais complicado que simplesmente pôr o BouncyCastle no CLASSPATH; você precisa copiar em jre/lib/ext, modificar jre/lib/security/java.security e outras coisas mais chatas) só para usar o BrazilUtils.
Poderíamos incluir as rotinas básicas de brazilutils.security no jar principal (a de senha só usa as rotinas básicas do Java, por exemplo) e as rotinas mais avançadas, que poucos usariam - como é o caso dessa rotina de análise de certificados - seriam incluídas em um outro jar.

Ugh!Jah é um exercício pô-la para rodar então…

É isso! :smiley: