问题
I write a bash script who manipulate hex values and i need to do XOR operation between two hexa numbers. My problem is when i try in bash prompt it's work and return right value but in script this value is false.
When XOR variable $ExtendAuthKey and $IPAD the result must be : 181ad673a5d94f0e12c8894ea26381b363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636
But in fact i get this value : 3906369333256140342
I dont understand this behavior, if you have explanation or solution i take it, thank
see my script : `
#!/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)
`
回答1:
If you do echo $((IPAD))
you will get 3906369333256140342
. The problem is that once you perform arithmetic operation in shell, your inputs get truncated to size of int
of your platform (in this case 64b). I suspect you will have to reach out beyond shell to perform the bitwise XOR (or process it in smaller chunks, but the md5 digest alone is already twice the size).
回答2:
As others have said, the issue you're facing is that the output of the xor is being truncated to 64-bits. You could still do it in the shell, you'd just need to break the arithmetic up into 64-bit chunks. I recently did this for kicks:
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
}
Example:
$ xor "0c60c80f961f0e71f3a9b524af6012062fe037a6" "e60cc942513261fd3eb76c0e617d53f6f73ebef1"
ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
This is a comically slow way to xor some big numbers, but for demos it should be fine. I used it in a PBKDF2 implementation where it reduced the output of 4096 rounds of HMAC SHA512 in a minute or so (concurrently with the hashing).
回答3:
Maybe this helps, using bc
:
a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
b=5555555555555555555555555555555555555555555555555555555555555555
bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
Output
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Note that the hex is in upper case, and that the <<<
is a "bashism" so, if you are not using bash
, you can turn it around and express it like this, and also prevent line breaks at the same time:
echo "obase=16;ibase=16;xor($a,$b)" | BC_LINE_LENGTH=0 bc -l logic.bc
It relies on the logic
additional library for bc
:
wget http://phodd.net/gnu-bc/code/logic.bc
回答4:
The output of bc is ASCII using xxd you need -u for processing UPPERCASE with xxd I got 46 instead of 41 with hexdump. NOTE THE logic.bc file isn't persistent on my machine.
This XOR's in Ubuntu 18 32bit Live Disc:
wget http://phodd.net/gnu-bc/code/logic.bc
Then assuming a constant 32 Bytes of data stream, using expr length $a may help
a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
The xor is performed with bc - l result was a string of A's which is 2's complement of 5 I piped it to hexdump appended "|hexdump
" and got: 41 In HEX is A ASCII CHAR
0000000 4141 4141 4141 4141 4141 4141 4141 4141
*
0000040 000a
0000041
@Mark Setchell Thank you for bc command. I did man bc and leaned alot. It was important to note the diferences between '^' parsing. Like with '$' Theres ambiguous definitions. So with C ^ means "XOR" and not "to the power of ...." And $ is sometimes used for strings or variables but in bash it invokes the bash command test out the differences between $0 and $(0)
Notes: At At 0000040 000a thats my line feed "Enter Key". Also note the output of hexdump is lowercase you can use tr to translate. On two's complement its the XOR(x) =
Disclaimer: Different environments can overload ^ and $ "operator" command for different results.
This experimental command has a problem with refreshing stdin see 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
This outputs bc results to xxd and prints $a in between the commands $a temporarily for some reason perhaps $(0) related injections xxd outputs 46 no 41 HEX ascii for A using -u with xxd seems to make no difference:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
4646464646464646464646464646464646464646464646464646464646464646
Below are the A and then B inputs
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
5555555555555555555555555555555555555555555555555555555555555555
This command helps with formatting the output of hexdump and removing the enter key the extra echo should be omitted in your code: a=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && b=5555555555555555555555555555555555555555555555555555555555555555 && bc -l logic.bc <<< "obase=16;ibase=16;xor($a,$b)" | hexdump -v -e '/1 "%02X"' | sed -e 's_0A__';echo
来源:https://stackoverflow.com/questions/48620882/how-to-xor-two-hex-numbers-in-bash-script-xor-encryption