O algoritmo de sintetização de mensagem MD5 é uma função hash amplamente utilizada que produz um valor de hash de 128 bits expresso em 32 caracteres.[1] Embora o MD5 tenha sido projetado inicialmente para ser usado como uma função hash criptográfica, foi constatado que ele sofre de extensas vulnerabilidades. Ele ainda pode ser usado como uma soma de verificação para checar a integridade de dados,[2] mas apenas contra corrupção não intencional. Ele permanece adequado para outros fins não criptográficos, por exemplo, para determinar a partição para uma chave específica em um banco de dados particionado.[3]

O MD5 foi projetado por Ronald Rivest em 1991 para substituir uma função hash anterior MD4,[4] e foi especificado em 1992 como RFC 1321.

Um requisito básico de qualquer função de hash criptográfico é que seja computacionalmente inviável encontrar duas mensagens distintas com hash para o mesmo valor. O MD5 falha com esse requisito catastroficamente; essas colisões podem ser encontradas em segundos em um computador doméstico comum.

As fraquezas do MD5 foram exploradas em campo, principalmente pelo malware Flame em 2012. O CMU Software Engineering Institute considera o MD5 essencialmente "criptograficamente quebrado e inadequado para uso posterior".[5] Em 2012, o malware Flame explorou os pontos fracos do MD5 para falsificar uma assinatura digital da Microsoft.

Em 2008, Ronald Rivest e outros, publicaram uma nova versão do algoritmo o MD6 com hash de tamanhos 224, 256, 384 ou 512 bits. O algoritmo MD6 iria participar do concurso para ser o novo algoritmo SHA-3,[6][7] porém logo depois removeu-o do concurso por considerá-lo muito lento, anunciando que os computadores de hoje são muito lentos para usar o MD6.

A partir de 2019, o MD5 continua sendo amplamente utilizado, apesar de suas fraquezas e depreciação bem documentadas por especialistas em segurança.[8]

Vulnerabilidade

editar

Como o MD5 faz apenas uma passagem sobre os dados, se dois prefixos com o mesmo hash forem construídos, um sufixo comum pode ser adicionado a ambos para tornar uma colisão mais provável. Deste modo é possível que duas strings diferentes produzam o mesmo hash. O que não garante que a partir de uma senha codificada em hash específica consiga-se a senha original, mas permite uma possibilidade de descobrir algumas senhas a partir da comparação de um conjunto grande de hash de senhas através do método de comparação de dicionários.

Pseudocódigo

editar

Segue-se um pseudocódigo para o algoritmo MD5

//Definir r como o seguinte
var int[64] r, k
r[ 0..15] := {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22}
r[16..31] := {5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20}
r[32..47] := {4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23}
r[48..63] := {6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21}
//Utilizar a parte inteira dos senos de inteiros como constantes:
for i from 0 to 63
    k[i] := floor(abs(sin(i   1)) × 2^32)
//Iniciar as variáveis:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476
//Pre-processamento:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message
//Processar a mensagem em pedaços sucessivos de 512-bits:
for each 512-bit chunk of message
    break chunk into sixteen 32-bit little-endian words w(i), 0 ≤ i ≤ 15
    //Inicializar o valor do hash para este pedaço:
    var int a := h0
    var int b := h1
    var int c := h2
    var int d := h3
    //Loop principal:
    for i from 0 to 63
        if 0 ≤ i ≤ 15 then
            f := (b and c) or ((not b) and d)
            g := i
        else if 16 ≤ i ≤ 31
            f := (d and b) or ((not d) and c)
            g := (5×i   1) mod 16
        else if 32 ≤ i ≤ 47
            f := b xor c xor d
            g := (3×i   5) mod 16
        else if 48 ≤ i ≤ 63
            f := c xor (b or (not d))
            g := (7×i) mod 16
        temp := d
        d := c
        c := b
        b := ((a   f   k[i]   w(g)) leftrotate r[i])   b
        a := temp
    //Adicionar este pedaço do hash ao resultado:
    h0 := h0   a
    h1 := h1   b
    h2 := h2   c
    h3 := h3   d
var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)

Nota: Ao invés da formulação do RFC 1321 acima exibida, considera-se mais eficiente a seguinte implementação:

(0  ≤ i ≤ 15): f := d xor (b and (c xor d))
(16 ≤ i ≤ 31): f := c xor (d and (b xor c))

Hashes MD5

editar

Os hashes MD5 de 128-bit (16-byte) são normalmente representados por uma sequência de 32 caracteres hexadecimais. O seguinte mostra uma string ASCII com 43-bytes e o hash correspondente:

 MD5("The quick brown fox jumps over the lazy dog")
  = 9e107d9d372bb6826bd81d3542a419d6

Mesmo uma pequena alteração na mensagem vai criar um hash completamente diferente, ex. ao mudar d para c:

 MD5("The quick brown fox jumps over the lazy cog")
  = 1055d3e698d289f2af8663725127bd4b

O Hash de uma string vazia é:

 MD5("")
  = d41d8cd98f00b204e9800998ecf8427e

Salgar (Salting)

editar

Para aumentar a segurança em alguns sistemas, usa-se a tática de adicionar um texto fixo no texto original a ser codificado. Deste modo se o sal for "wiki" e a senha for "1234", a pseudo-senha poderá ser "wiki1234" e assim mesmo que alguém tenha o MD5 de 1234 por ser uma senha comum ele não terá de wiki1234. Porém caso o "sal" seja simples como no exemplo e houver o MD5 de "wiki1234" é possível descobrir o sal e deste modo decodificar as senhas mais comuns. Por este motivo geralmente o "sal" é algo complexo.

Ver também

editar

Ligações externas

editar

Referências

  1. «Calculates the md5 hash of a given file». contest-server.cs.uchicago.edu. Consultado em 18 de agosto de 2020 
  2. Joshua Turteen (15 de janeiro de 2012). «Hashing Is Not Encryption». Marcelo Alvarez. Consultado em 23 de junho de 2014 
  3. Kleppmann, Martin (2 de abril de 2017). Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems 1 ed. [S.l.]: O'Reilly Media. p. 203. ISBN 978-1449373320 
  4. Ciampa, Mark (2009). CompTIA Security 2008 in depth. Australia ; United States: Course Technology/Cengage Learning. p. 290. ISBN 978-1-59863-913-1. (pede registo (ajuda)) 
  5. Chad R, Dougherty (31 de dezembro de 2008). «Vulnerability Note VU#836068 MD5 vulnerable to collision attacks». Vulnerability notes database. CERT Carnegie Mellon University Software Engineering Institute. Consultado em 3 de fevereiro de 2017 
  6. Ronald Rivest, The MD6 hash function A proposal to NIST for SHA-3
  7. «Federal Register / Vol. 72, No. 212» (PDF). Federal Register. Government Printing Office. 2 de novembro de 2007. Consultado em 6 de novembro de 2008 
  8. Cimpanu, Catalin. «A quarter of major CMSs use outdated MD5 as the default password hashing scheme». ZDNet (em inglês). Consultado em 17 de junho de 2019