Manually calculating JWT signature never outputs the real signature - jwt

I've been reading a lot of questions on stackOverflow and jwt's docs.
Right now from what I understand this is what I should do to calculate a token:
header =
{
"alg": "HS256",
"typ": "JWT"
}
payload =
{
"sub": "1234567890",
"name": "JohnDoe",
"iat": 1516239022
}
secret = "test123"
Remove unnecessary spaces and breaklines from header and payload and then encoding both to base64url.
base64urlEncode(header)
// output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
base64urlEncode(payload)
// output: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjJ9
Same output as on jwt.io, perfect.
Calculate the sha256 hmac using "test123" as secret.
sha256_hmac("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjJ9", "test123)
// output: 3b59324118bcd59a5435194120c2cfcb7cf295f25a79149b79145696329ffb95
Convert the hash to string and then base64url encode it.
I use hex to string converter for this part, then I encode it using base64urlEncode and I get the following output:
O1kyQRjCvMOVwppUNRlBIMOCw4_Di3zDssKVw7JaeRTCm3kUVsKWMsKfw7vClQ
Output from jwt.io
O1kyQRi81ZpUNRlBIMLPy3zylfJaeRSbeRRWljKf-5U
But if I go to this page From Hex, to Base64 I get the correct output:
O1kyQRi81ZpUNRlBIMLPy3zylfJaeRSbeRRWljKf-5U
So what am I doing wrong? Why converting the hex to string and then Encoding it outputs a different result?
In case the online hex to string conversion is wrong, how can I convert this hex to string (so then I can encode it) on c++ without using any libray. Am I correct if I convert each byte (2 characters because hex = 4 bits) to ASCII character and then encode?
Thanks in advance.

Your hmac step is correct, does have the right output bytes (as commented). The conversion problem you have is caused by non-display chars in the temporary string (the raw bytes were not correctly copied pasted from first webpage to second).
To reproduce the exact output at each stage, you can use these commands below.
In terms of C++, you should try to operate on the raw bytes, rather than on the hex string. Take the raw bytes and run them through a base64 URL-safe encoder. Or, as in the example below, take the raw bytes, run them through a plain base64 encoder, and then fix the generated base64 string to be URL safe.
Construct the header
jwt_header=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)
# ans: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Construct the payload
payload=$(echo -n '{"sub":"1234567890","name":"JohnDoe","iat":1516239022}' | base64 | sed s/\+/-/g |sed 's/\//_/g' | sed -E s/=+$//)
# ans: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjJ9
Raw password
secret="test123"
Convert secret to hex (not base64)
hexsecret=$(echo -n "$secret" | xxd -p | tr -d '\n')
# ans: 74657374313233
Perform hmac, and capture the raw bytes (caution, this is a non printable string)
hmac_signature_rawbytes=$(echo -n "${jwt_header}.${payload}" | openssl dgst -sha256 -mac HMAC -macopt hexkey:$hexsecret -binary)
Dump the raw bytes as hex, for illustration only (matches OP output)
echo -n ${hmac_signature_rawbytes} | xxd -p | tr -d '\n'
#ans: 3b59324118bcd59a5435194120c2cfcb7cf295f25a79149b79145696329ffb95
For JWT signature, convert raw bytes to base64uri encoding
hmac_signature=$(echo -n ${hmac_signature_rawbytes} | base64 | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)
#ans: O1kyQRi81ZpUNRlBIMLPy3zylfJaeRSbeRRWljKf-5U
Create the full token
jwt="${jwt_header}.${payload}.${hmac_signature}"
# ans: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.O1kyQRi81ZpUNRlBIMLPy3zylfJaeRSbeRRWljKf-5U

Related

Understanding ibase and obase used

I'm trying to solve the following exercise:
Write a command line that takes numbers from variables FT_NBR1, in ’\"?! base, and FT_NBR2, in mrdoc base, and displays the sum of both in gtaio luSnemf base.
I know the solution is:
echo $FT_NBR1 + $FT_NBR2 | sed 's/\\/1/g' | sed 's/?/3/g' | sed 's/!/4/g' | sed "s/\'/0/g" | sed "s/\"/2/g" | tr "mrdoc" "01234" | xargs echo "ibase=5; obase=23;" | bc | tr "0123456789ABC" "gtaio luSnemf"
I don't understand why ibase=5 and obase=23.
I read about ibase and obase, and I understand this is a base conversion, from base 5 to base 23. Anyone can explain me why 5 and 23. Thank you
The exercise description is a bit weird. A better one would be
Write a command line that takes numbers from variables FT_NBR1, with numbers represented by the letters "’\"?!", and FT_NBR2, represented by "mrdoc", and displays the sum of both with numbers represented by "gtaio luSnemf".
A shorter answer would be
echo $FT_NBR1 + $FT_NBR2 | tr "\'\\\\\"\?" "01234" | tr "mrdoc" "01234" | xargs echo "ibase=5; obase=23;" | bc | tr "0123456789ABC" "gtaio luSnemf"
Let's take it from the beginning:
echo $FT_NBR1 + $FT_NBR2 creates the expression using the input strings
tr "\'\\\\\"\?" "01234" translates the first input alphabet into numbers
tr "mrdoc" "01234" translates the second input alphabet into numbers
xargs echo "ibase=5; obase=23;" prepends number base information; the input base is 5 and the output base is 13, but obase must be expressed in the base of ibase and 13 in base 5 is 23.
bc does the actual calculation
tr "0123456789ABC" "gtaio luSnemf" does the translation into the output alphabet.

Can I get objdump --full-contents to only print the raw text?

I have an object file which with a section containing proper ASCII (or Latin-1?) text. So, if I write:
$ objdump -s my_file.so --section=.rodata
looks like this (only presenting a few lines from the middle, it's obviously very long):
070a80 656d3b0a 73697a65 5f742073 68617265 em;.size_t share
070a90 644d656d 50657242 6c6f636b 3b0a696e dMemPerBlock;.in
070aa0 74207265 67735065 72426c6f 636b3b0a t regsPerBlock;.
070ab0 696e7420 77617270 53697a65 3b0a7369 int warpSize;.si
070ac0 7a655f74 206d656d 50697463 683b0a69 ze_t memPitch;.i
070ad0 6e74206d 61785468 72656164 73506572 nt maxThreadsPer
070ae0 426c6f63 6b3b0a69 6e74206d 61785468 Block;.int maxTh
My question: Can I get objdump to just print the text, without the line indices and the hexadecimal values? And to print at least all the printing characters properly (e.g. a newline for 0x0a)? Or - must I perform a bunch of text processing to correlate the dots to their values, replace them with the proper characters, cut the line prefixes, drop the artificial newlines etc?
Use xxd
Using xxd will avoid cuting and awking, and is your best solution short of a objdump flag.
Saving your formatted hexdump to file temp, we can pipe the result to xxd -r, (which expects such a formatted hexdump):
$ cat temp | xxd -r
em;
size_t sharedMemPerBlock;
int regsPerBlock;
int warpSize;
size_t memPitch;
int maxThreadsPerBlock;
int maxTh
If you need to pass in a hex string with no line numbers or ascii representation instead, use xxd -r -p.

Unicode confusion #3423435

Once again I enter that goddamn unicode-hell ... sigh =(
There are two files:
$ file *
kreise_tmp.geojson: ASCII text
pandas_tmp.csv: UTF-8 Unicode text
I read the first file like this:
with open('kreise_tmp.geojson') as f:
jdata = json.loads(f.read())
I read the second file like this:
pandas_data = pd.read_csv(r'pandas_tmp.csv', sep=";")
Now check out what's inside the strings:
>>> jdata['features'][0]['properties']['name']
u'Kreis Euskirchen' # a unicode string?
>>> pandas_data['kreis'][0]
'Kreis D\xc3\xbcren' # not a unicode string?
Why are the strings from the "UTF-8 Unicode text" file just normal strings and the strings from the "ASCII text" file unicode strings?
JSON strings are always Unicode.
~$ python2
>>> import json
>>> json.loads('"\xc3\xbc"')
u'\xfc'
But they are often serialized with \u escapes, so file will only see ASCII.
>>> json.dumps(_)
'"\\u00fc"'
add encoding='utf-8' to the opening of files to decode them with utf-8
pandas_data = pd.read_csv(r'pandas_tmp.csv', sep=";", encoding='utf8')
you can also do the same with the JSON
with open('kreise_tmp.geojson', encoding='utf8') as f:
jdata = json.loads(f.read())
Also in Python 2.7, you can add this to the top of the file..
#!/usr/bin/env python
# -*- coding: utf-8 -*-

Perl: How to process HTTP response with encode_base64

I have an task to generate an BASE64 string from HTTP response which will be used by the external program.Before I was doing this,I had known that if you use BASE64,the length of the string will be extend like 57 * 4/3 = 76.
But I've no idea which need to be handle if the HTTP respone longer than 57 bytes! So I had not any special handle for the HTTP response,just direct covert "$response->content" to which I want.(Actually length of the response more than 57 bytes).
3.The unexpected thing is that the length of the encode string not excatly follow 4/3 rule!!! When the len of input string is 57,then len of encode string is 77. When the len of input string is 114, the encode string is 154,why?
4.When I try to use the BASE64 output from an external c# arg(),seems it can only receive first 57 bytes.
#Sample Code
my $cont = $response->content;
$cont = substr ($cont, 0, 57);
my $encode = encode_base64($cont);
printf("Length Before Decode = %d.\n",length($cont));
printf("Length After Decode = %d.\n",length($encode));
#
According to this note, encode_base64() adds a newline. Are you counting that newline in the encoded string length? It seems to account for your extra character.

sed replacement value between to matches

Hi I want to replace a string coming between to symbols by using sed
example: -amystring -bxyz
what to replace mystring with ****
value after -a can be anything like -amystring 123 -bxyz, -amystring 123<newline_char>, -a'mystring 123' -bxyz, -a'mystring 123'<newline_char>
I tried following regex but it does not work in all the cases
sed -re "s#(-w)([^\s\-]+)#\1**** #g"
can anybody help me to solve this issue ?
MyString="YourStringWithoutRegExSpecialCharNotEscaped"
sed "s/-a${MyString} -b/-a**** -b/g"
if you can escape your string for any regex key char like * + . \ / with something like
echo "${MyString}" | sed 's/\[*.\\/+?]/\\&/g' | read -r MyString
before us it in sed.
otherwise, you need to better define the edge pattern