【问题标题】:How to XOR two hex numbers in bash script? (XOR Encryption)如何在 bash 脚本中异或两个十六进制数字? (异或加密)
【发布时间】:2018-07-15 05:01:46
【问题描述】:

我编写了一个操作十六进制值的 bash 脚本,我需要在两个十六进制数之间进行异或运算。我的问题是当我在 bash 提示符下尝试时,它可以工作并返回正确的值,但在脚本中这个值是假的。

当变量 $ExtendAuthKey 和 $IPAD 异或时,结果必须是: 181ad673a5d94f0e12c8894ea26381b363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636

但实际上我得到了这个值:3906369333256140342

我不明白这种行为,如果您有解释或解决方案我接受它,谢谢

查看我的脚本: `

#!/bin/bash

AuthID=80001f8880e9bd0c1d12667a5100000000

IPAD=0x36363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636
OPAD=0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c
Ext0=0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

WholeMsgIn=0x3081800201033011020420dd06a7020300ffe30401050201030431302f041180001f8880e9bd0c1d12667a5100000000020105020120040475736572040c00000000000000000000000004003035041180001f8880e9bd0c1d12667a51000000000400a11e02046b4c5ac20201000201003010300e060a2b06010201041e0105010500

line=test

#Calcule AuthKey
  AuthKey=$(snmpkey md5 $line $AuthID | grep auth | cut -d ' ' -f 2)

#Concat AuthKey + Ext0
  ExtendAuthKey=$AuthKey${Ext0:2}

#Calcule de K1 = ExtendAuthKey XOR IPAD
  K1=$(( $ExtendAuthKey ^ $IPAD ))

#Calcule de K2 = ExtendAuthKey XOR OPAD
  K2=$(( $ExtendAuthKey ^ $OPAD ))

#Concat K1 + WholeMsgIn
  Concat1=$K1$WholeMsgIn

#Calcul Hash Concat1
  echo ${Concat1:2} > tempH.hex
  cat tempH.hex | xxd -r -p > tempB.bin
  HashConcat1=$(md5sum tempB.bin | cut -d ' ' -f 1)

#Concat K2 + Concat1
  Concat2=$K2$HashConcat1

#Calcul Hash Concat1
  echo ${Concat2:2} > tempH.hex
  cat tempH.hex | xxd -r -p > tempB.bin
  HashConcat2=$(md5sum tempB.bin | cut -d ' ' -f 1)

`

【问题讨论】:

    标签: bash encryption xor encryption-symmetric bitwise-xor


    【解决方案1】:

    如果您执行echo $((IPAD)),您将获得3906369333256140342。问题是,一旦您在 shell 中执行算术运算,您的输入就会被截断为您平台的 int 大小(在本例中为 64b)。我怀疑你将不得不超越 shell 来执行按位异或(或以更小的块处理它,但仅 md5 摘要就已经是两倍大小)。

    【讨论】:

    • 感谢您的回复,您对“echo $((IPAD))”的看法是对的
    • 乐于助人。是的,这有点意味着你会默默地丢失信息,但为了公平起见,文档提到:算术评估:...评估是在固定宽度的整数中完成的,没有检查溢出...
    【解决方案2】:

    也许这有帮助,使用bc:

    a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    b=5555555555555555555555555555555555555555555555555555555555555555
    bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
    

    输出

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    

    请注意,十六进制是大写,并且&lt;&lt;&lt; 是一个“bashism”,因此,如果您不使用bash,您可以转过来这样表达,同时也防止换行:

    echo "obase=16;ibase=16;xor($a,$b)" | BC_LINE_LENGTH=0 bc -l logic.bc 
    

    它依赖于logic 附加库bc

    wget http://phodd.net/gnu-bc/code/logic.bc
    

    【讨论】:

    • 感谢但它返回一个错误(standard_in)当我在脚本测试它:a = 37b79b510c6ba2c6d71abea2dc100e2d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 B = 5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c BC -l logic.bc
    • 哦。您是否下载了库并在与库相同的目录中运行?它适用于较小的数字吗?
    • 是的,我在同一个目录中运行我的脚本,我有同样的错误,但数字较小。我也直接在提示符下进行测试,它的工作,这个错误(standard_in)只出现在脚本中。
    • 您可以反过来运行命令,看看是否有帮助,&lt;&lt;&lt;bashism,所以如果您使用 shzsh 等,它将不起作用。试试echo "obase=16;ibase=16;xor($a,$b)" | bc -l logic.bc
    • 我在网上搜索,但我不知道什么是 bashism,你有关于它的文档链接吗?我用管道测试命令但不工作并返回与 相同的错误
    【解决方案3】:

    bc 的输出是ASCII,使用 xxd 你需要 -u 来处理 xxd 的大写我得到 46 而不是 hexdump 的 41。注意 logic.bc 文件在我的机器上不是持久的。

    这个 XOR 在 Ubuntu 18 32 位 Live Disc 中:

    wget http://phodd.net/gnu-bc/code/logic.bc
    

    然后假设一个恒定的 32 字节数据流,使用 expr 长度 $a 可能会有所帮助

    a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    

    xor 是用 bc 执行的 - l 结果是一个 A 的字符串,它是 5 的 2 的补码我将它传送到附加“|hexdump”的 hexdump 并得到:41 In HEX is A ASCII CHAR

    0000000 4141 4141 4141 4141 4141 4141 4141 4141
    *
    0000040 000a                                   
    0000041
    

    @Mark Setchell 感谢您提供 bc 命令。我做了 man bc 并且倾斜了很多。重要的是要注意 '^' 解析之间的差异。就像 '$' 有模棱两可的定义。因此,C ^ 表示“XOR”而不是“...的幂” $ 有时用于字符串或变量,但在 bash 中它调用 bash 命令测试 $0 和 $(0) 之间的差异

    注意:在 0000040 000a 那是我的换行符“Enter Key”。还要注意 hexdump 的输出是小写的,你可以使用 tr 来翻译。在二进制补码上,它的 XOR(x) =

    免责声明: 不同的环境可以重载 ^ 和 $ "operator" 命令以获得不同的结果。

    这个实验性命令有一个刷新标准输入的问题man xxd

    a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)" && echo $a | xxd -l 32 -ps -c 64 && echo "Below are the A and then B inputs" && echo $a && echo $b
    

    这会将 bc 结果输出到 xxd 并在命令 $a 之间临时打印 $a 出于某种原因可能与 $(0) 相关的注射 xxd 输出 46 no 41 HEX ascii for A using -u with xxd 似乎可以没有区别:

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    4646464646464646464646464646464646464646464646464646464646464646
    Below are the A and then B inputs
    FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    5555555555555555555555555555555555555555555555555555555555555555
    

    此命令有助于格式化 hexdump 的输出并删除回车键,应在代码中省略额外的回显: a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc

    【讨论】:

    • xxd -u 在 ubuntu 18 上不适合我这是否意味着 XOR 加密失败?
    • 这在我的 bash 中对 XOR 命令不起作用 #Calcule de K1 = ExtendAuthKey XOR IPAD K1=$(( $ExtendAuthKey ^ $IPAD )) #Calcule de K2 = ExtendAuthKey XOR OPAD K2=$(( $ExtendAuthKey ^ $OPAD ))
    • xxd -e 将切换到小端而不是大端。
    【解决方案4】:

    正如其他人所说,您面临的问题是 xor 的输出被截断为 64 位。您仍然可以在 shell 中执行此操作,只需将算术分解为 64 位块。我最近这样做是为了好玩:

    xor() {
      {
        echo "${1}" | # start pipeline with first parameter
          fold -w 16 | # break into 16 char lines (note: 4-bit hex char * 16 = 64 bits)
          sed 's/^/0x/' | # prepend '0x' to lines to tell shell their hex numbers
          nl # number the lines (we do this to match corresponding ones)
        echo "${2}" | # do all the same to the second parameter
          fold -w 16 | 
          sed 's/^/0x/' | 
          nl
      } | # coming into this pipe we have lines: 1,...,n,1,...,n 
      sort -n | # now sort so lines are: 1,1,...,n,n
      cut -f 2 | # cut to keep only second field (blocks), ditching the line numbers
      paste - - | # paste to join every-other line with tabs (now two-field lines)
      while read -r a b; do # read lines, assign 'a' and 'b' to the two fields 
        printf "%#0${#a}x" "$(( a ^ b ))" # do the xor and left-pad the result
      done |
      sed 's/0x//g' | # strip the leading '0x' (here for clarity instead of in the loop)
      paste -s -d '\0' - # join all the blocks back into to a big hex string
    }
    

    例子:

    $ xor "0c60c80f961f0e71f3a9b524af6012062fe037a6" "e60cc942513261fd3eb76c0e617d53f6f73ebef1"
    ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
    

    这是异或一些大数字的一种非常缓慢的方法,但对于演示来说应该没问题。我在 PBKDF2 实现中使用了它,它在一分钟左右的时间内减少了 4096 轮 HMAC SHA512 的输出(与散列同时进行)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 2014-01-15
      • 2016-08-03
      • 2014-01-01
      • 2013-06-28
      相关资源
      最近更新 更多