2009-12-05 14 views
3

Il semble qu'il existe une implémentation de HMAC dans toutes les langues sous le soleil. (Voir ci-dessous.) Et l'algorithme est assez simple:HMAC (code d'authentification de message basé sur le hachage, aka signature de données) dans Mathematica

http://en.wikipedia.org/wiki/HMAC

Quelqu'un at-il mis en œuvre dans Mathematica?

Voici des pointeurs vers des implémentations dans d'autres langues:

Répondre

5

Voici mon implémentation:

D'abord quelques fonctions utilitaires:

(* Pad the string s with x on the right/left so it has length n. *) 
strpadr[s_, n_, x_] := [email protected][Characters[s], n, x] 
strpadl[s_, n_, x_] := [email protected][Characters[s], n, x] 

(* hex representation; optionally pad to length n with zeros *) 
hex[x_, n_:Null]:= If[n===Null, Identity, strpadl[#,n,"0"]&]@IntegerString[x,16] 

(* parse hex representation (return an integer) *) 
unhex[x_] := FromDigits[x, 16] 

(* Concatenate all the arguments as strings (if they're not already). *) 
cat = StringJoin @@ (ToString /@ {##}) &; 

(* Takes a string like "xy" and returns the hex representation (also a string, 
    twice as long) of the bytes (ascii codes). *) 
tobytes[s_] := cat @@ (hex[#, 2] & /@ ToCharacterCode[s]) 

(* Takes a length n string like "0a10" and returns a length n/2 string where in 
    this example the first character is whatever has ascii code 10 ("a" in hex) 
    and the second is whatever has ascii code 16 ("10" in hex). *) 
frombytes[hs_] := FromCharacterCode[unhex /@ [email protected]@@Partition[Characters[hs], 2]] 

(* Bitwise-xor of two integers given in hex. *) 
hexbitxor[a_String, b_String] := [email protected][[email protected], [email protected]] 

(* Repeat the string s, n times. *) 
strrpt[s_, n_] := cat @@ ConstantArray[s, n] 

(* Byte length of a hex string is half the string length. *) 
bytelen[s_] := Ceiling[StringLength[s]/2] 

mise en œuvre des fonctions de hachage de base dans Mathematica est pas tout à fait banal. Voir cette question: Cryptographic hash (sha1 or md5) of data given as a string in Mathematica.

(* FileHash is the only way to hash data given as a string in Mma. *) 
hash[s_String, h_:"SHA"] := Module[{stream = StringToStream[s], result}, 
    result = FileHash[stream, h]; 
    Close[stream]; 
    [email protected]]; 
sha1[s_] := hash[s] 
md5[s_] := hash[s, "MD5"] 

Enfin, voici la fonction HMAC:

(* Return the hmac digest using hash function h for string s with key k. *) 
hmac[s_, k_, h_:sha1] := Module[{b, key, ipad, opad}, 
    b = 64; (* block size for both md5 and sha1 *) 
    key = tobytes[k]; 
    key = If[bytelen[key] > b, h[[email protected]], key]; 
    key = strpadr[key, 2 b, "0"]; 
    ipad = hexbitxor[strrpt["36", b], key]; 
    opad = hexbitxor[strrpt["5c", b], key]; 
    h[frombytes[opad <> h[frombytes[ipad <> [email protected]]]]]] 

Je confirme que cela correspond à tous les exemples fournis dans RFC 2104. Par exemple:

hmac["what do ya want for nothing?", "Jefe", md5] 

retours

"750c783e6ab0b503eaa86e310a5db738"