如何在bash脚本中对两个十六进制数进行XOR运算? (XOR加密)

时间:2018-02-05 10:50:22

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

我编写了一个操作十六进制值的bash脚本,我需要在两个六进制数之间进行XOR运算。我的问题是,当我尝试在bash提示符下工作并返回正确的值但在脚本中该值为false。

当XOR变量$ 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)

`

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

使用function childSize () { var parentHeight = document.getElementById( HAVE PARENTS ID HERE ).offsetHeight; parentHeight = parentHeight / 100 * 120; document.getElementById( HAVE CHILD C ID HERE ).offsetHeight = parentHeight; }

可能会有所帮助
bc

<强>输出

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

请注意,十六进制是大写AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &#34; bashism&#34; 所以,如果你不是使用<<<,您可以将其翻转并像这样表达,同时也可以防止换行:

bash

它依赖于echo "obase=16;ibase=16;xor($a,$b)" | BC_LINE_LENGTH=0 bc -l logic.bc 的{​​{1}}附加库:

logic

答案 2 :(得分:0)

使用xxd,bc的输出为ASCII,您需要使用-u来处理xxd的大写字母,而使用hexdump则得到46而不是41。注意logic.bc文件在我的计算机上不是永久的。

Ubuntu 18 32bit Live Disc中的此XOR:

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

用bc执行异或-结果是A的字符串,它是2的5的补数,我将其通过管道添加到附加在“ |hexdump”的hexdump中,得到:41在十六进制中是ASCII字符

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

@Mark Setchell感谢您的bc命令。我做了公元前,并倾斜了很多。重要的是要注意“ ^”解析之间的区别。与“ $”类似,那里的定义不明确。因此,对于C ^,它的意思是“异或”,而不是“……的力量”。 $有时用于字符串或变量,但是在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否41使用-u和xxd的A的十六进制ascii没什么区别:

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

此命令有助于格式化hexdump的输出并删除回车键,否则应在代码中省略多余的回声:  a = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b = 5555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<<“ obase = 16; ibase = 16; xor($ a,$ b)” | | hexdump -v -e'/ 1“%02X”'| | sed -e's_0A __'; echo

答案 3 :(得分:0)

正如其他人所说,您面临的问题是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的输出。