如何对 bash 脚本中的两个十六进制数字进行异或? (异或加密)
How to XOR two hex numbers in bash script? (XOR Encryption)
我写了一个 bash 脚本来处理十六进制值,我需要在两个十六进制数之间进行异或运算。我的问题是当我在 bash 中尝试提示它工作并且 return 正确的值但是在脚本中这个值是错误的。
当 XOR 变量 $ExtendAuthKey 和 $IPAD 结果必须是:
181ad673a5d94f0e12c8894ea26381b363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636=313636[6363636=313636]
但实际上我得到了这个值: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)
`
如果你echo $((IPAD))
你会得到3906369333256140342
。问题是,一旦您在 shell 中执行算术运算,您的输入就会被截断为平台的 int
大小(在本例中为 64b)。我怀疑您将不得不超越 shell 来执行按位异或(或以较小的块处理它,但单独的 md5 摘要已经是大小的两倍)。
也许这有帮助,使用 bc
:
a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
b=5555555555555555555555555555555555555555555555555555555555555555
bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
输出
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
注意十六进制是大写,<<<
是"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
bc 的输出是 ASCII 使用 xxd 你需要 -u 来用 xxd 处理大写 我用 hexdump 得到 46 而不是 41。注意 logic.bc 文件在我的机器上不是持久的。
此 XOR 在 Ubuntu 18 32 位 Live Disc 中:
wget http://phodd.net/gnu-bc/code/logic.bc
然后假设恒定的 32 字节数据流,使用 expr length $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 在 HEX 中是一个 ASCII CHAR
0000000 4141 4141 4141 4141 4141 4141 4141 4141
*
0000040 000a
0000041
@Mark Setchell 感谢 bc 命令。我做了 man bc 并且倾斜了很多。重要的是要注意“^”解析之间的差异。与 '$' 一样,定义不明确。所以 C ^ 意味着 "XOR" 而不是 "to the power of ...."
$ 有时用于字符串或变量,但在 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=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)" | | | hexdump -v -e '/1 "%02X"' | sed -e 's_0A__';echo
正如其他人所说,您面临的问题是 xor 的输出被截断为 64 位。您仍然可以在 shell 中执行此操作,您只需要将算术分解为 64 位块。我最近这样做是为了好玩:
xor() {
{
echo "" | # 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 "" | # 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 '[=10=]' - # join all the blocks back into to a big hex string
}
示例:
$ xor "0c60c80f961f0e71f3a9b524af6012062fe037a6" "e60cc942513261fd3eb76c0e617d53f6f73ebef1"
ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
这是一种对一些大数字进行异或的慢得可笑的方法,但对于演示来说应该没问题。我在 PBKDF2 实现中使用它,它在一分钟左右(与散列同时)减少了 4096 轮 HMAC SHA512 的输出。
我写了一个 bash 脚本来处理十六进制值,我需要在两个十六进制数之间进行异或运算。我的问题是当我在 bash 中尝试提示它工作并且 return 正确的值但是在脚本中这个值是错误的。
当 XOR 变量 $ExtendAuthKey 和 $IPAD 结果必须是: 181ad673a5d94f0e12c8894ea26381b363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636=313636[6363636=313636]
但实际上我得到了这个值: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)
`
如果你echo $((IPAD))
你会得到3906369333256140342
。问题是,一旦您在 shell 中执行算术运算,您的输入就会被截断为平台的 int
大小(在本例中为 64b)。我怀疑您将不得不超越 shell 来执行按位异或(或以较小的块处理它,但单独的 md5 摘要已经是大小的两倍)。
也许这有帮助,使用 bc
:
a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
b=5555555555555555555555555555555555555555555555555555555555555555
bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
输出
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
注意十六进制是大写,<<<
是"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
bc 的输出是 ASCII 使用 xxd 你需要 -u 来用 xxd 处理大写 我用 hexdump 得到 46 而不是 41。注意 logic.bc 文件在我的机器上不是持久的。
此 XOR 在 Ubuntu 18 32 位 Live Disc 中:
wget http://phodd.net/gnu-bc/code/logic.bc
然后假设恒定的 32 字节数据流,使用 expr length $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 在 HEX 中是一个 ASCII CHAR
0000000 4141 4141 4141 4141 4141 4141 4141 4141
*
0000040 000a
0000041
@Mark Setchell 感谢 bc 命令。我做了 man bc 并且倾斜了很多。重要的是要注意“^”解析之间的差异。与 '$' 一样,定义不明确。所以 C ^ 意味着 "XOR" 而不是 "to the power of ...." $ 有时用于字符串或变量,但在 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=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)" | | | hexdump -v -e '/1 "%02X"' | sed -e 's_0A__';echo
正如其他人所说,您面临的问题是 xor 的输出被截断为 64 位。您仍然可以在 shell 中执行此操作,您只需要将算术分解为 64 位块。我最近这样做是为了好玩:
xor() {
{
echo "" | # 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 "" | # 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 '[=10=]' - # join all the blocks back into to a big hex string
}
示例:
$ xor "0c60c80f961f0e71f3a9b524af6012062fe037a6" "e60cc942513261fd3eb76c0e617d53f6f73ebef1"
ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
这是一种对一些大数字进行异或的慢得可笑的方法,但对于演示来说应该没问题。我在 PBKDF2 实现中使用它,它在一分钟左右(与散列同时)减少了 4096 轮 HMAC SHA512 的输出。