O Hash é uma sequência de bits que tem como objetivo identificar um arquivo. Isso significa que se realizarmos um processamento num arquivo será gerado um Hash que é único, e dessa forma, alcançamos a garantia da integridade. Utilizando o Hash também temos a propriedade da unidirecionalidade onde o caminho de volta não é possível. Além disso, utilizando Hash não há a necessidade de chaves e, temos a garantia da consistência, pois se introduzirmos a mesma mensagem de Hash teremos exatamente o mesmo Hash sendo gerado. Por fim, o Hash também nos oferece as propriedades de randomicidade e unicidade onde nunca temos a mesma mensagem de Hash para diferentes mensagens.
Um dos problemas do Hash é que estamos vulneráveis a ataques de dicionário. Um ataque de dicionário é onde um atacante tem um banco de dados de senhas prováveis com seus respectivos Hashs. Como uma solução para este problema tem-se o SALT que é uma porção aleatória de texto que é concatenado com a senha original, e assim sendo, por exemplo, pessoas com mesma senha obterão Hashs diferentes.
A saída das mensagens criptografadas com Hash é independente da entrada, sempre temos como saída 128 bits. Por exemplo, uma letra "a" tem como saída 128 bits, um texto de 10 MB também gera como saída um Hash de 128 bits. Os Hashs também oferecem a noção de colisão que é quando duas mensagens produzem o mesmo Hash.
Leia mais em: Como funciona a Criptografia Hash em Java http://www.devmedia.com.br/como-funciona-a-criptografia-hash-em-java/31139#ixzz3KzqiLbtmLetra A
podemos afirmar que para qualquer função de hash haverão colisões. Portanto, resistência à colisões não significa que não deve existir colisões, mas sim que: “embora colisões existam, elas não podem ser encontradas.” (FERGUSON, 2003)
E, é claro, quanto maior o valor do hash de uma função de hash, mais difícil é encontrar colisões. Assim, é muito mais difícil encontrar uma colisão com uma função de hash de 256bits do que com uma função de hash de 128bits.