How to XOR two hex numbers in bash script? (XOR Encryption)

青春壹個敷衍的年華 提交于 2019-12-13 03:44:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!