[RESOLVIDO][Criptografia SHA] O que é o byte? como pegar o código em SHA e não HEX?

Pessoal,

Estou começando a mexer com a criptografia SHA, o que entendi até agora é que pega-se o getBytes() de uma string, dessa matriz de byte é criado um código através do algoritmo SHA, e que do byte[] desse código é transformado pra hexa para que não contenha caracter especial, é isso?

Gostaria de saber se quando eu chamo o MessageDigest.digest() a matriz de byte q é retornada é a matriz de byte do código SHA? como eu consigo o código gerado pelo algoritmo SHA? por que trabalhamos com os bytes dos dados?

Poderiam me ajudar?

Poneis,

Esse tipo de criptografia não envolve chaves sendo assim, a forma para mascaras esse tipo de informação é simplesmente, não conseguir fazer a engenharia reversa no mesmo. Esse tipo de algoritmo faz uso do que chamamos de “Algoritmos de Espalhamento”.

Sendo assim, caso voce queria validar se um conteúdo de um string qualquer é o conteúdo cripgrafado, a única forma é voce aplicar o algoritmo (no caso o SHA) e comparar o resultado.

  • eu menti um pouco…na verdade, já é possível fazer eng reversa em MD5 e SHA1 =)

kkkkkk entendi, o ideal era q não tivesse a eng reversa né rs

Eu fiz a pergunta, mas fuçando um pouco aqui eu entendi:
É que a forma que eu to usando ele pega o código gerado pelo algoritmo SHA e transforma o byte dele em hexadecimal… pra descobrir exatamente o código SHA gerado pelo algoritmo basta usar por exemplo:

String senha = "abc123"; MessageDigest md = MessageDigest.getInstance( "SHA" ); md.update(senha.getBytes()); byte[] byteSHA = md.digest(); System.out.println("Conversão da senha em SHA : " + new String(byteSHA));

Nunca converta um array de bytes para uma string com new String(byte[]), assim como você fez. É que isso costuma alterar alguns bytes para valores incorretos.

Converta o array de bytes para hexadecimal. Uma forma de fazer isso é com esta função:

public String toHex (byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        sb.append (String.format ("%02X", b & 0xFF));
    }
    return sb.toString();
}

Mas converte-lo para hexa não é a solução de new String(byte[]), são coisas diferentes…
eu to pegando o valor em byte[] e convertendo pra string… é o inverso de “abc”.getBytes() que me retorna um byte[] a partir de uma String, eu to voltando o byte para a String.

Deu pra entender o q eu to fazendo? Se tiver outra forma de se fazer isso posta ae.

Valew brother!

É mesmo? Dessa eu não sabia… Você poderia dar mais detalhes?

Claro que entendi. Quando você obtém o SHA-1 de alguma coisa, obtém 20 bytes que podem ser considerados “completamente aleatórios”, no sentido que todos eles podem ir de 0 até 255. Só que se você usar new String(byte[]) em um array de bytes desse tipo, vai dar problemas, porque cerca de 30 valores possíveis entre 0 até 255 não são convertidos corretamente de byte[] para char usando new String(byte[]). Eles são convertidos para o caracter ‘?’, e isso vai dar problemas sérios.
A única maneira de você ter um resultado confiável, se for converter um array de bytes para string, é convertê-lo para hexadecimal (como fiz) ou outra representação como base-64. Nunca use diretamente new String(byte[]) a menos que você saiba o que está fazendo (que não é, obviamente, o caso).

entanglement, Agora entendi!! realmente, quando eu faço essa conversão me traz uma string toda doida… se eu apresentar ela na tela e usar um ctrl+c nela pra colar em outro lugar já era… perde alguma coisa no meio do caminho… acredito eu q seja pq alguns desses bytes não são representados graficamente né? mas se eu utilizar essa String para passar para outro lugar e voltar a pegar o getBytes() dele funciona normal… só não posso confiar na String que é apresentada na tela.

Valew pela ajuda ae, clareou totalmente.

Funciona normal uma ova. Vou mostrar aqui que não funciona normal coisa nenhuma.

class TesteGetBytes { public static void main(String[] args) { byte[] bytes = new byte[256]; for (int i = 0; i < 256; ++i) { bytes[i] = (byte) i; } System.out.printf ("Comprimento do array de bytes original = %d %n", bytes.length); String s = new String (bytes); byte[] bytes2 = s.getBytes(); System.out.printf ("Comprimento do array de bytes final = %d %n", bytes2.length); for (int i = 0; i < 256; ++i) { if (bytes[i] != bytes2[i]) { System.out.printf ("Byte %02X: original = %02X != final = %02X %n", i, bytes[i] & 0xFF, bytes2[i] & 0xFF); } } } }
Rode o programa acima. Você vai obter o seguinte resultado em uma máquina Windows:

Comprimento do array de bytes original = 256
Comprimento do array de bytes final = 256
Byte 81: original = 81 != final = 3F
Byte 8D: original = 8D != final = 3F
Byte 8F: original = 8F != final = 3F
Byte 90: original = 90 != final = 3F
Byte 9D: original = 9D != final = 3F

Em uma máquina Linux, você vai ficar chocado, porque o array original é menor que o array final.
O impresso será:

Comprimento do array de bytes original = 256 
Comprimento do array de bytes final = 503 
Byte 80: original = 80 != final = EF 
Byte 81: original = 81 != final = BF 
Byte 82: original = 82 != final = BD 
Byte 83: original = 83 != final = EF 
Byte 84: original = 84 != final = BF 
Byte 85: original = 85 != final = BD 
Byte 86: original = 86 != final = EF 
Byte 87: original = 87 != final = BF 
Byte 88: original = 88 != final = BD 
Byte 89: original = 89 != final = EF 
Byte 8A: original = 8A != final = BF 
Byte 8B: original = 8B != final = BD 
Byte 8C: original = 8C != final = EF 
Byte 8D: original = 8D != final = BF 
Byte 8E: original = 8E != final = BD 
Byte 8F: original = 8F != final = EF 
Byte 90: original = 90 != final = BF 
Byte 91: original = 91 != final = BD 
Byte 92: original = 92 != final = EF 
Byte 93: original = 93 != final = BF 
Byte 94: original = 94 != final = BD 
Byte 95: original = 95 != final = EF 
Byte 96: original = 96 != final = BF 
Byte 97: original = 97 != final = BD 
Byte 98: original = 98 != final = EF 
Byte 99: original = 99 != final = BF 
Byte 9A: original = 9A != final = BD 
Byte 9B: original = 9B != final = EF 
Byte 9C: original = 9C != final = BF 
Byte 9D: original = 9D != final = BD 
Byte 9E: original = 9E != final = EF 
Byte 9F: original = 9F != final = BF 
Byte A0: original = A0 != final = BD 
Byte A1: original = A1 != final = EF 
Byte A2: original = A2 != final = BF 
Byte A3: original = A3 != final = BD 
Byte A4: original = A4 != final = EF 
Byte A5: original = A5 != final = BF 
Byte A6: original = A6 != final = BD 
Byte A7: original = A7 != final = EF 
Byte A8: original = A8 != final = BF 
Byte A9: original = A9 != final = BD 
Byte AA: original = AA != final = EF 
Byte AB: original = AB != final = BF 
Byte AC: original = AC != final = BD 
Byte AD: original = AD != final = EF 
Byte AE: original = AE != final = BF 
Byte AF: original = AF != final = BD 
Byte B0: original = B0 != final = EF 
Byte B1: original = B1 != final = BF 
Byte B2: original = B2 != final = BD 
Byte B3: original = B3 != final = EF 
Byte B4: original = B4 != final = BF 
Byte B5: original = B5 != final = BD 
Byte B6: original = B6 != final = EF 
Byte B7: original = B7 != final = BF 
Byte B8: original = B8 != final = BD 
Byte B9: original = B9 != final = EF 
Byte BA: original = BA != final = BF 
Byte BB: original = BB != final = BD 
Byte BC: original = BC != final = EF 
Byte BD: original = BD != final = BF 
Byte BE: original = BE != final = BD 
Byte BF: original = BF != final = EF 
Byte C0: original = C0 != final = BF 
Byte C1: original = C1 != final = BD 
Byte C2: original = C2 != final = EF 
Byte C3: original = C3 != final = BF 
Byte C4: original = C4 != final = BD 
Byte C5: original = C5 != final = EF 
Byte C6: original = C6 != final = BF 
Byte C7: original = C7 != final = BD 
Byte C8: original = C8 != final = EF 
Byte C9: original = C9 != final = BF 
Byte CA: original = CA != final = BD 
Byte CB: original = CB != final = EF 
Byte CC: original = CC != final = BF 
Byte CD: original = CD != final = BD 
Byte CE: original = CE != final = EF 
Byte CF: original = CF != final = BF 
Byte D0: original = D0 != final = BD 
Byte D1: original = D1 != final = EF 
Byte D2: original = D2 != final = BF 
Byte D3: original = D3 != final = BD 
Byte D4: original = D4 != final = EF 
Byte D5: original = D5 != final = BF 
Byte D6: original = D6 != final = BD 
Byte D7: original = D7 != final = EF 
Byte D8: original = D8 != final = BF 
Byte D9: original = D9 != final = BD 
Byte DA: original = DA != final = EF 
Byte DB: original = DB != final = BF 
Byte DC: original = DC != final = BD 
Byte DD: original = DD != final = EF 
Byte DE: original = DE != final = BF 
Byte DF: original = DF != final = BD 
Byte E0: original = E0 != final = EF 
Byte E1: original = E1 != final = BF 
Byte E2: original = E2 != final = BD 
Byte E3: original = E3 != final = EF 
Byte E4: original = E4 != final = BF 
Byte E5: original = E5 != final = BD 
Byte E6: original = E6 != final = EF 
Byte E7: original = E7 != final = BF 
Byte E8: original = E8 != final = BD 
Byte E9: original = E9 != final = EF 
Byte EA: original = EA != final = BF 
Byte EB: original = EB != final = BD 
Byte EC: original = EC != final = EF 
Byte ED: original = ED != final = BF 
Byte EE: original = EE != final = BD 
Byte F0: original = F0 != final = BF 
Byte F1: original = F1 != final = BD 
Byte F2: original = F2 != final = EF 
Byte F3: original = F3 != final = BF 
Byte F4: original = F4 != final = BD 
Byte F5: original = F5 != final = EF 
Byte F6: original = F6 != final = BF 
Byte F7: original = F7 != final = BD 
Byte F8: original = F8 != final = EF 
Byte F9: original = F9 != final = BF 
Byte FA: original = FA != final = BD 
Byte FB: original = FB != final = EF 
Byte FC: original = FC != final = BF 
Byte FD: original = FD != final = BD 
Byte FE: original = FE != final = EF 
Byte FF: original = FF != final = BF 

Conclusão: NUNCA CONVERTA UM ARRAY DE BYTES PARA UMA STRING SEM SABER O QUE VOCÊ ESTÁ FAZENDO. VOCÊ NÃO SABE O QUE ESTÁ FAZENDO.

Só um detalhe conceitual: criptografia pressupõe uma função reversível, ou seja, é possível voltar ao texto claro a partir do texto criptografado com a função de decifragem. Funções como SHA-1 ou MD5 são chamadas funções hash, onde o retorno ainda que possível é inviável. E essa é só uma das diferenças.

entanglement, de todos os bytes q vc passou 5 deram erro para voltar. No meu funcionou normal a volta pq não usa esses bytes =P mas é realmente arriscado se não se sabe o conteúdo da String.