Anar al contingut

HMAC

De L'Enciclopèdia, la wikipedia en valencià
HMAC
SHA-1 HMAC Generation.

En la criptografia, un HMAC (a voltes expandit com a còdic d'autentificació de mensages en clau-hash o còdic d'autenticació de mensage basat en hash) és una construcció específica per a calcular un còdic d'autentificació de mensage (MAC) que implica una funció hash criptográfica en combinació en una clau criptográfica secreta. Com qualsevol MAC, pot ser utilisat per a verificar simultàneament la integritat de les senyes i la autentificació d'un mensage. Qualsevol funció hash criptográfica, tals com SHA-2 o SHA-3, pot ser utilisada per al càlcul d'un HMAC; l'algoritme MAC resultant es denomina HMAC-SHA2 o HMAC-SHA3 en conseqüència. La força criptográfica de el HMAC depén de la potència criptográfica de la funció de hash subjacent, el tamany de la seua eixida de hash i el tamany i calitat de la clau.

Una funció hash iterativa trenca un mensage en blocs d'un tamany fix i itera sobre ells en una funció de compressió. Per eixemple, SHA-2 i SHA-3 operen en blocs de 512-bit. El tamany de l'eixida de HMAC és el mateix que el de la funció de hash subjacent (entre 224 i 512 bits en el cas de SHA3 dependent de la configuració).

La definició i l'anàlisis de la construcció HMAC es va publicar per primera volta en 1996 per Mihir Bellare, Ran Canetti i Hugo Krawczyk, que també va escriure el RFC 2104. Aixina mateix, este document definix una variant anomenada NMAC que rara volta, o mai, s'utilisa. FIPS PUB 198 generalisa i estandardisa l'us de HMAC. HMAC-SHA1 i HMAC-MD5 s'utilisen dins dels protocols IPsec i TLS pero no són segurs hui dia.

Definició (de RFC 2104)

[editar | editar còdic]

𝐻𝑀𝐴𝐶(K,m)=H((Kopad)||H((Kipad)||m))

a on:

H és una funció hash criptográfica,
K és una clau secreta reblix a la dreta en zeros adicionals al tamany del bloc d'entrada de la funció hash, o el hash de la clau original si és més llarc que el tamany de bloc,
m és el mensage a ser autenticado,
|| denota concatenació,
⊕ denota disjunció exclusiva (XOR),
opad és la farcidura exterior (0x5c5c5c…5c5c, un bloc de llarc hexadecimal constant),
ipad és la farcidura interior (0x363636…3636, un bloc de llarc hexadecimal constant).

Implementació

[editar | editar còdic]

El següent pseudocódigo mostra cóm es pot implementar HMAC. El tamany del bloc és de 64 (bytes) quan s'utilisa una de les següents funcions hash: SHA-1, MD5, RIPEMD-128/160.[1]

function hmac (key, message)
    if (length(key) > blocksize) then
        key = hash(key) // claus en més tamany que el bloc s'acurten al tamany just aplicant hash a eixes claus
    end if
    if (length(key) < blocksize) then
        key = key ∥ [0x00 * (blocksize - length(key))] // claus més curtes que el tamany del bloc s'engrandixen en zeros (a on  és la concatenació)
    end if
   
    o_key_pad = [0x5c * blocksize] ⊕ key // Quan el tamany del bloc és el de la funció de hash subjacent
    i_key_pad = [0x36 * blocksize] ⊕ key // A on ⊕ és l'o exclusiu (XOR)
   
    return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // A on  és la concatenació
end function

El següent és una implementació en Python de HMAC-MD5:

#!/usr/bin/env python

from hashlib import md5

trans_5C = bytearray((x ^ 0x5c) for x in range(256))
trans_36 = bytearray((x ^ 0x36) for x in range(256))
blocksize = md5().block_size # 64


def hmac_md5(key, msg):
    if len(key) > blocksize:
        key = md5(key).digest()
    key = key + bytearray(blocksize - len(key))
    o_key_pad = key.translate(trans_5C)
    i_key_pad = key.translate(trans_36)
    return md5(o_key_pad + md5(i_key_pad + msg).digest())

if __name__ == "__main__":
    #  Est és un eixemple de l'apèndix de la RFC 2104    
    h = hmac_md5(b"Cap", b"what do ya want for nothing?")
    print(h.hexdigest()) # 750c783i6ab0b503eaa86i310a5db738

Python inclou un mòdul hmac,[2] per lo que la funció anterior pot ser reemplaçada per una versió més curta.

import hmac
from hashlib import md5

def hmac_md5(key, msg):
    return hmac.HMAC(key, msg, md5)

El següent còdic és una implementació en PHP de HMAC-SHA1:

function sha1_hmac(&#36;key,&#36;data,&#36;blockSize=64,&#36;opad=0x5c,&#36;ipad=0x36) {

    // Claus de més tamany que el bloc s'acurten
    if (strlen(&#36;key) > &#36;blockSize) {
        &#36;key = sha1(&#36;key,true);	
    }
    
    // Claus més curtes que el tamany de bloc són reblides en zeros a la dreta (concatenat)
    &#36;key       = str_pad(&#36;key,&#36;blockSize,chr(0x00),STR_PAD_RIGHT);	
    &#36;o_key_pad = &#36;i_key_pad = '';
    
    for(&#36;i = 0;&#36;i < &#36;blockSize;&#36;i++) {
        &#36;o_key_pad .= chr(ord(substr(&#36;key,&#36;i,1)) ^ &#36;opad);
        &#36;i_key_pad .= chr(ord(substr(&#36;key,&#36;i,1)) ^ &#36;ipad);
    }
    
    return sha1(&#36;o_key_pad.sha1(&#36;i_key_pad.&#36;data,true),true);
}

&#36;hmac = sha1_hmac('key','The quick brown fox jumps over the lazy dog');

PHP inclou una funció HMAC,[3] per lo que l'eixemple anterior pot ser reemplaçat per una versió més curta.

<?php
hash_hmac('sha1', 'The quick brown fox jumps over the lazy dog', 'key');

La següent és una implementació usant QCryptographicHash de Qt <syntaxhighlight lang="cpp"> QByteArray hmacSha256(QByteArray key, const QByteArray& message) { const int blocksize = 64; if (key.length() > blocksize) QCryptographicHash::hash(key, QCryptographicHash::Sha256);

while (key.length() < blocksize) key.append('


Referències

[editar | editar còdic]
  1. RFC 2104, section 2, "Definition of HMAC", page 3.
  2. «hmac — Keyed-Hashing for Message Authentication».Python Software Foundation.Consultat el 7 de maig de 2014.
  3. «PHP: hash_hmac - Manual».The PHP Group.Consultat el 13 de setembre de 2015.