【问题标题】:HMAC (hash-based message authentication code, aka data signing) in MathematicaMathematica 中的 HMAC(基于哈希的消息验证码,又名数据签名)
【发布时间】:2009-12-05 07:17:07
【问题描述】:

似乎在所有语言中都有 HMAC 的实现。 (见下文。) 而且算法非常简单:

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

有人在 Mathematica 中实现过吗?

这里是指向其他语言实现的指针:

【问题讨论】:

    标签: authentication hash code-signing wolfram-mathematica


    【解决方案1】:

    这是我的实现:

    首先是一些实用功能:

    (* Pad the string s with x on the right/left so it has length n. *)
    strpadr[s_, n_, x_] := StringJoin@PadRight[Characters[s], n, x]
    strpadl[s_, n_, x_] := StringJoin@PadLeft[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 /@ cat@@@Partition[Characters[hs], 2]]
    
    (* Bitwise-xor of two integers given in hex. *)
    hexbitxor[a_String, b_String] := hex@BitXor[unhex@a, unhex@b]
    
    (* 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]
    

    在 Mathematica 中实现基本的哈希函数并非易事。看到这个问题: 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];
      hex@result];
    sha1[s_] := hash[s]
    md5[s_] := hash[s, "MD5"]
    

    最后是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[frombytes@key], 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 <> tobytes@s]]]]]
    

    我确认这符合RFC 2104 中提供的所有示例。例如:

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

    返回

    "750c783e6ab0b503eaa86e310a5db738"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      相关资源
      最近更新 更多