shell和脚本中的不同MD5输出

时间:2015-03-26 12:02:18

标签: bash shell echo fritzbox

这让我抓狂,我试图根据fritzbox SPEC进行一些MD5计算登录。基本上你必须将挑战和密码转换为UTF-16LE,然后用md5哈希,然后连续挑战 - MD5(UFT-16LE(挑战 - 密码))

为此,我在脚本中使用mac OSX中的iconv和md5

echo -n "challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5

哪些输出到2f42ad272c7aec4c94f0d9525080e6de

通过在shell输出中将其粘贴到1722e126192656712a1d352e550f1317

来完成确切的操作

后者是正确的(fritzbox接受)第一个是错误的。

使用bash script.sh调用脚本会导致正确的哈希值,使用sh script.sh调用它会导致错误的哈希值,从而导致出现一个新问题:sh和bash之间的输出结果如何不同?

2 个答案:

答案 0 :(得分:3)

echo的不同版本以非常不同的方式表现。有些命令选项(如-n)修改了它们的行为(包括-n抑制尾随换行符),有些则没有。有些解释字符串本身的转义序列(包括字符串末尾的\c抑制尾随换行符)......而有些则不然。有些人都这样做。您系统上的echo(/ bin / echo)版本似乎没有选项,因此将-n视为要打印的字符串。如果你正在使用bash,它的内置版本会覆盖/ bin / echo,而解释标志。

基本上,echo是一堆不一致和可移植性陷阱。所以不要使用它,而是使用printf。这有点复杂,因为你必须指定一个格式字符串,然后是你想要打印的实际内容,但它可以节省大量的麻烦。

$ printf "%s" "challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5
1722e126192656712a1d352e550f1317

顺便说一句,这是echo命令实际打印的内容:

$ printf "%s\n" "-n challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5
2f42ad272c7aec4c94f0d9525080e6de

答案 1 :(得分:0)

您特别要求脚本和命令行结果之间的区别。请注意,可能存在其他情况,其中脚本结果将无法用于您的Fritzbox。

AVM Fritzbox文档中会话处理的示例代码是用C#编写的

从该代码我派生https://github.com/WolfgangFahl/fritz-csharp-api 并添加了一些测试:

受到以下测试的启发:

基本上有5个例子:

  1. “” - > “d41d8cd98f00b204e9800998ecf8427e”
  2. “secret”,“09433e1853385270b51511571e35eeca”
  3. “test”,“c8059e2ec7419f590e79d7f1b774bfe6”
  4. “1234567z-äbc”,“9e224a41eeefa284df7bb0f26c2913e2”;
  5. “!\”§$%& /()=?ßüäöÜÄÖ - 。,;:_`'+ *#'<>≤|“ - >”ad44a7cb10a95cb0c4d7ae90b0ff118a“ 你的是现在的第6号示例:
  6. “challenge-password1234” - > “1722e126192656712a1d352e550f1317” 这些在Java和C#实现中表现相同。现在使用下面的bash脚本尝试这些

    echo -n“$ l_s”| iconv --from-code ISO8859-1 - to-code UTF-16LE | md5sum -b | gawk'{print substr($ 0,1,32)}'

  7. 例如在https://www.ip-phone-forum.de/threads/fritzbox-challenge-response-in-sh.264639/

    中讨论过

    因为它的getmd5函数为Umlaut情况提供了不同的结果,例如在我的Mac OS Sierra上的bash中。

    已经添加了一些调试输出。

    为1234567z-äbc给出的编码具有字节序列2d c3 a4 62 63,例如java实现有2d e4 62 63.

    因此请注意密码中的变音符号 - 使用此脚本解决方案时,fritzbox访问可能会失败。我正在寻找一种解决方法,并在找到它时将其发布在此处。

    bash脚本

    #!/bin/bash
    # WF 2017-10-30
    # Fritzbox handling
    
    #
    # get the property with the given name
    # params
    #   1: the property name e.g. fritzbox.url, fritzbox.username, fritzbox.password
    #
    getprop() {
      local l_prop="$1"
      cat $HOME/.fritzbox/application.properties | grep "$l_prop" | cut -f2 -d=
    }
    
    #
    # get a value from the fritzbox login_sid.lua
    #
    getboxval() {
      local l_node="$1"
      local l_response="$2"
      if [ "$l_response" != "" ]
      then
        l_data="&response=$l_response"
      fi
      fxml=/tmp/fxml$$
      curl --insecure -s "${box_url}/login_sid.lua?username=${username}$l_response" > $fxml
      cat $fxml |
      gawk -v node=$l_node 'match($0,"<"node">([0-9a-f]+)</"node">",m) { print m[1] }'
      cat $fxml
      rm $fxml
    }
    
    #
    # get the md5 for the given string
    #
    # see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID.pdf
    #
    # param
    #  1: s - the string
    #
    # return
    #   md5 
    #
    getmd5() {
      local l_s="$1"
      echo -n "$l_s" | iconv -f ISO8859-1 -t UTF-16LE | od -x
      echo -n "$l_s" | iconv --from-code ISO8859-1 --to-code UTF-16LE | md5sum -b | gawk '{print substr($0,1,32)}'
    }
    
    # get global settings from application properties
    box_url=$(getprop fritzbox.url)
    username=$(getprop fritzbox.username)
    password=$(getprop fritzbox.password)
    
    # uncomment to test
    getmd5 ""
    #   should be d41d8cd98f00b204e9800998ecf8427e
    getmd5 secret
    #   should be 09433e1853385270b51511571e35eeca
    getmd5 test
    #   should be c8059e2ec7419f590e79d7f1b774bfe6
    getmd5 1234567z-äbc
    #   should be 9e224a41eeefa284df7bb0f26c2913e2
    getmd5 "!\"§$%&/()=?ßüäöÜÄÖ-.,;:_\`´+*#'<>≤|"
    #   should be ad44a7cb10a95cb0c4d7ae90b0ff118a
    exit
    # Login and get SID
    challenge=$(getboxval Challenge "")
    echo "challenge=$challenge"
    md5=$(getmd5 "${challenge}-${password}")
    echo "md5=$md5"
    response="${challenge}-${md5}" 
    echo "response=$response" 
    getboxval SID "$response"