Gente, estou precisando de um código que leia o MD5 de uma senha que o usuario escrever.
Esse era o problema inicial, mas vi que tem melhores criptografias por aí.
packagenet.viralpatel.java.md5;importjava.math.BigInteger;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;publicclassJavaMD5Hash{publicstaticvoidmain(String[]args){Stringpassword="MyPassword123";System.out.println("MD5 in hex: "+md5(password));System.out.println("MD5 in hex: "+md5(null));//= d41d8cd98f00b204e9800998ecf8427eSystem.out.println("MD5 in hex: "+md5("The quick brown fox jumps over the lazy dog"));//= 9e107d9d372bb6826bd81d3542a419d6}publicstaticStringmd5(Stringinput){Stringmd5=null;if(null==input)returnnull;try{//Create MessageDigest object for MD5MessageDigestdigest=MessageDigest.getInstance("MD5");//Update input string in message digestdigest.update(input.getBytes(),0,input.length());//Converts message digest value in base 16 (hex) md5=newBigInteger(1,digest.digest()).toString(16);}catch(NoSuchAlgorithmExceptione){e.printStackTrace();}returnmd5;}}
Se quiser fazer em Java puro, esse enum que montei pode te ajudar:
importjava.io.ByteArrayOutputStream;importjava.io.DataOutputStream;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;publicenumHash{MD5("MD5"),SHA1("SHA-1"),SHA256("SHA-256");privateStringalgo;privateHash(Stringalgo){this.algo=algo;}publicbyte[]diggest(byte[]dados){try{MessageDigestalgorithm=MessageDigest.getInstance(algo);returnalgorithm.digest(dados);}catch(NoSuchAlgorithmExceptione){thrownewRuntimeException("Unable to generate password!",e);}}publicStringdiggest(Stringvalor){returnbyteArrayToString(diggest(stringToByteArray(valor)));}privateStringbyteArrayToString(byte[]byteArray){StringBuildersb=newStringBuilder();for(byteb:byteArray){intvalue=b&0xFF;if(value<16)sb.append("0");sb.append(Integer.toString(value,16));}returnsb.toString();}privatebyte[]stringToByteArray(Stringvalor){ByteArrayOutputStreambos=newByteArrayOutputStream();try(DataOutputStreamdos=newDataOutputStream(bos)){dos.writeUTF(valor);}catch(Exceptione){assert(false);// Nunca ocorre com ByteArrays}returnbos.toByteArray();}}
S
SirDominque
ViniGodoy:
Se quiser fazer em Java puro, esse enum que montei pode te ajudar:
importjava.io.ByteArrayOutputStream;importjava.io.DataOutputStream;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;publicenumHash{MD5("MD5"),SHA1("SHA-1"),SHA256("SHA-256");privateStringalgo;privateHash(Stringalgo){this.algo=algo;}publicbyte[]diggest(byte[]dados){try{MessageDigestalgorithm=MessageDigest.getInstance(algo);returnalgorithm.digest(dados);}catch(NoSuchAlgorithmExceptione){thrownewRuntimeException("Unabletogeneratepassword!",e);}}publicStringdiggest(Stringvalor){returnbyteArrayToString(diggest(stringToByteArray(valor)));}privateStringbyteArrayToString(byte[]byteArray){StringBuildersb=newStringBuilder();for(byteb:byteArray){intvalue=b&0xFF;if(value<16)sb.append("0");sb.append(Integer.toString(value,16));}returnsb.toString();}privatebyte[]stringToByteArray(Stringvalor){ByteArrayOutputStreambos=newByteArrayOutputStream();try(DataOutputStreamdos=newDataOutputStream(bos)){dos.writeUTF(valor);}catch(Exceptione){assert(false);// Nunca ocorre com ByteArrays}returnbos.toByteArray();}}
Obrigado Professor.
Só uma pergunta, tem alguma diferenca do "java-puro" para a API da apache ?
V
ViniGodoy
Andre Lopes:
Obrigado Professor.
Só uma pergunta, tem alguma diferenca do “java-puro” para a API da apache ?
Não precisa incluir a API do Apache.
E é um pouco mais difícil de usar.
S
SirDominque
ViniGodoy:
Andre Lopes:
Obrigado Professor.
Só uma pergunta, tem alguma diferenca do “java-puro” para a API da apache ?
Não precisa incluir a API do Apache.
E é um pouco mais difícil de usar.
Professor, muito Obrigado.
Ja implementei a classe e criptografei o nome de um amigo meu para testar.
Como ainda não li o livro do deitel, não sei se esta correto.
O sr, poderia verificar pra mim ,por favor?
packageSecurity;importcom.mysql.jdbc.PreparedStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassValidate{privateStringemailInserted,passwordInserted,codeInserted;protectedStringdriverName,serverName,myDataBase;privateConnectionconn=null;publicstaticvoidmain(Stringargs[]){Validatev1=newValidate();//v1.Validate();v1.setStrongHash("Weiner");}publicbooleanValidate(){booleanvalid=false;//If valid == true, permitir acesso; Se valid == false, travar acesso;Stringorder=null;try{conn=DriverManager.getConnection("URL","username of database","password of database");order="Select * From Validator Where email = ? and password = ? and code = ? ";PreparedStatementstmt=(PreparedStatement)conn.prepareStatement("Select * From Validator Where email = ? and password = ? and code = ? ");// Coluna 0 = IDstmt.setString(0,emailInserted);// Coluna 1stmt.setString(1,passwordInserted);// Coluna 2stmt.setString(2,codeInserted);// Coluna 3ResultSetqueryAnswer=stmt.executeQuery();StringidFromDb=null;idFromDb=queryAnswer.getString(0);StringemailFromDb=null;emailFromDb=queryAnswer.getString(1);StringpasswordFromDb=null;passwordFromDb=queryAnswer.getString(2);StringcodeFromDb=null;codeFromDb=queryAnswer.getString(3);conn.commit();conn.close();//Compara os Dadosif(idFromDb!=null){if(emailFromDb.equals(emailInserted)){if(passwordFromDb.equals(passwordInserted)){if(codeFromDb.equals(codeInserted)){valid=true;}}}}elsevalid=false;if((valid==true)&&(idFromDb!=null)&&(emailFromDb!=null)&&(passwordFromDb!=null)&&(codeFromDb!=null))returnvalid;}catch(SQLExceptionex){System.out.println(ex.getMessage());}returnfalse;}publicStringsetStrongHash(Stringcode){StringhashCode=null;Hashh=null;Stringhashcode=h.SHA256.diggest(code);System.out.println(""+hashcode);returnhashCode;}<blockquote>run:8415c1bf09e34f7577a50414a7683aaa4f579fcbda392b89d45fd7ccbcc1e9e0CONSTRUÍDOCOMSUCESSO(tempototal:2segundos)</blockquote>}
R
rafaelob
É bem simples de usar com a API do apache.
Só chamar assim:
onde text é uma String com o que você quer criptografar em sha2 =). Esse método retorna uma string sha2
DigestUtils.sha256Hex(text)
V
ViniGodoy
A parte do Hash em si me parece ser isso mesmo. Faltou apenas algumas boas práticas.
Substitua essa linha:
importcom.mysql.jdbc.PreparedStatement;
Por essa:
importjava.sql.PreparedStatement;
Além de remover a dependência ao mysql, isso vai te permitir eliminar o cast da linha 34.
PreparedStatementstmt=conn.prepareStatement("Select * From Validator Where email = ? and password = ? and code = ? ");
Evite usar SELECT *. Descreva o nome das colunas no SELECT.
Não tem porque fazer essas declarações em duas linhas:
Faz em uma só que fica mais legível, além disso, use a coluna por nome, não por índice (isso evita que seu código quebre caso o banco mude):
StringidFromDb=queryAnswer.getString("email");
Pode usar o enum diretamente, evitando a criação da variável:
Stringhashcode=Hash.SHA256.diggest(code);
Use o try with resources para garantir que seu Statement e Connection sejam fechados, mesmo no caso de uma exceção ou de um return.
S
SirDominque
Professor, fiz o que o senhor me disse.
Ainda vou estudar o try-with-resources pra entender melhor.Aí em seguida ja posto o resultado.
Segue o Código :
packageSecurity;importjava.sql.PreparedStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassValidate{privateStringemailInserted,passwordInserted,codeInserted;protectedStringdriverName,serverName,myDataBase;privateConnectionconn=null;publicstaticvoidmain(Stringargs[]){Validatev1=newValidate();//v1.Validate();v1.setStrongHash("Weiner");}publicbooleanValidate(){booleanvalid=false;//If valid == true, permitir acesso; Se valid == false, travar acesso;Stringorder=null;try{conn=DriverManager.getConnection("URL","username of database","password of database");order="Select id,email,password,code from validator where email = ? and password = ? and code = ? ";PreparedStatementstmt=conn.prepareStatement("Select * From Validator Where email = ? and password = ? and code = ? ");// Coluna 0 = IDstmt.setString(0,emailInserted);// Coluna 1stmt.setString(1,passwordInserted);// Coluna 2stmt.setString(2,codeInserted);// Coluna 3ResultSetqueryAnswer=stmt.executeQuery();StringidFromDb=queryAnswer.getString("id");StringemailFromDb=queryAnswer.getString("email");StringpasswordFromDb=queryAnswer.getString("password");StringcodeFromDb=queryAnswer.getString("code");conn.commit();conn.close();//Compara os Dadosif(idFromDb!=null){if(emailFromDb.equals(emailInserted)){if(passwordFromDb.equals(passwordInserted)){if(codeFromDb.equals(codeInserted)){valid=true;}}}}elsevalid=false;if((valid==true)&&(idFromDb!=null)&&(emailFromDb!=null)&&(passwordFromDb!=null)&&(codeFromDb!=null))returnvalid;}catch(SQLExceptionex){System.out.println(ex.getMessage());}returnfalse;}publicStringsetStrongHash(Stringcode){Hashh=null;Stringhashcode=h.SHA512.diggest(code);System.out.println(""+hashcode);returnhashcode;}}
S
SirDominque
[quote=rafaelob]É bem simples de usar com a API do apache.
Só chamar assim:
onde text é uma String com o que você quer criptografar em sha2 =). Esse método retorna uma string sha2
DigestUtils.sha256Hex(text)
Depois eu vou tentar valeu
S
SirDominque
ViniGodoy:
Se quiser fazer em Java puro, esse enum que montei pode te ajudar:
importjava.io.ByteArrayOutputStream;importjava.io.DataOutputStream;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;publicenumHash{MD5("MD5"),SHA1("SHA-1"),SHA256("SHA-256");privateStringalgo;privateHash(Stringalgo){this.algo=algo;}publicbyte[]diggest(byte[]dados){try{MessageDigestalgorithm=MessageDigest.getInstance(algo);returnalgorithm.digest(dados);}catch(NoSuchAlgorithmExceptione){thrownewRuntimeException("Unabletogeneratepassword!",e);}}publicStringdiggest(Stringvalor){returnbyteArrayToString(diggest(stringToByteArray(valor)));}privateStringbyteArrayToString(byte[]byteArray){StringBuildersb=newStringBuilder();for(byteb:byteArray){intvalue=b&0xFF;if(value<16)sb.append("0");sb.append(Integer.toString(value,16));}returnsb.toString();}privatebyte[]stringToByteArray(Stringvalor){ByteArrayOutputStreambos=newByteArrayOutputStream();try(DataOutputStreamdos=newDataOutputStream(bos)){dos.writeUTF(valor);}catch(Exceptione){assert(false);// Nunca ocorre com ByteArrays}returnbos.toByteArray();}}
Professor, tenho uma dúvida, li um tópico aqui no fórum, e o rapaz informou no post mais ou menos isso :
""
Se o S.O estiver usando outra coisa além de UNICODE, o hash será diferente ...
""
Verdade isso ?
J
josue_carrecon
Andre Lopes:
“”
Se o S.O estiver usando outra coisa além de UNICODE, o hash será diferente …
“”
Verdade isso ?
Qual outra coisa??
G
Gleidson_Henrique
josue carrecon:
Andre Lopes:
“”
Se o S.O estiver usando outra coisa além de UNICODE, o hash será diferente …
“”
Verdade isso ?
Qual outra coisa??
UTF-8, UTF-16…
Mas acredito que não tem nada a ver visto que o mesmo hash pra mim, é o mesmo hash que alguem vai utilizar em qualquer pc do mundo… senao, isso de hashs seria totalmente um enorme problema.
Imagina voce fazer o backup de um banco de dados e passar para um outro SO em que a codificação seja diferente? Todos hashs bem dizer seriam diferentes do que foi gerado anteriormente no outro sistema…
Abraços
O
oyama
O problema de Message Digest (MD) por causa de charset/encoding ocorre na maneira que você representa o byte array, pois geralmente o que se faz é transformar uma representação em hexa ou uma codificação tipo base64. Se usar o default do sistema opracional (SO), o seu programa pode não funcionar se gerar o MD em um SO e verificar em outro SO (tipo Linux e Windows).
S
SirDominque
Valeu gente!
O que eu devo mudar na classe para não ter esse problema?
packageSecurity;importjava.io.ByteArrayOutputStream;importjava.io.DataOutputStream;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importsun.security.rsa.RSASignature;publicenumHash{MD5("MD5"),SHA1("SHA-1"),SHA256("SHA-256"),SHA512("SHA-512");privateStringalgo;privateHash(Stringalgo){this.algo=algo;}publicbyte[]diggest(byte[]dados){try{MessageDigestalgorithm=MessageDigest.getInstance(algo);returnalgorithm.digest(dados);}catch(NoSuchAlgorithmExceptione){thrownewRuntimeException("Unable to generate password!",e);}}publicStringdiggest(Stringvalor){returnbyteArrayToString(diggest(stringToByteArray(valor)));}privateStringbyteArrayToString(byte[]byteArray){StringBuildersb=newStringBuilder();for(byteb:byteArray){intvalue=b&0xFF;if(value<16)sb.append("0");sb.append(Integer.toString(value,16));}returnsb.toString();}privatebyte[]stringToByteArray(Stringvalor){ByteArrayOutputStreambos=newByteArrayOutputStream();try(DataOutputStreamdos=newDataOutputStream(bos)){dos.writeUTF(valor);}catch(Exceptione){assert(false);// Nunca ocorre com ByteArrays }returnbos.toByteArray();}}
S
SirDominque
Gente,Alguns usuários meus de outros países nao estao conseguindo logar com o programa. Estou achando que o Erro é nesse HASH.
Da erro de login.
O que voces me sugerem fazer?
G
Gleidson_Henrique
Mostra o hash com um JOptionPane e compare com o do db para ver se está diferente…
Mas se aqui do brasil está ok, provavelmente está com problema mesmo.