4

这让我发疯,我试图根据 fritzbox SPEC 进行一些 MD5 计算以进行登录。基本上你必须将挑战和密码转换为 UTF-16LE,然后通过 md5 对其进行哈希处理,然后 concat challenge-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 之间的输出有何不同?

4

2 回答 2

3

不同版本的echo行为方式非常不同。有些采用命令选项(如-n)来修改其行为(包括-n抑制尾随换行),有些则不采用。有些解释字符串本身中的转义序列(包括\c在字符串末尾抑制尾随换行)......而有些则没有。有些人两者都做。您系统上的 (/bin/echo) 版本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
于 2015-03-26T17:24:05.093 回答
0

您专门询问脚本和命令行结果之间的区别。请注意,在其他情况下,脚本结果可能无法用于您的 Fritzbox。

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

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

受到以下测试的启发:

基本上有5个例子:

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

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

例如在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"
于 2017-10-30T18:00:14.033 回答