android - Java vs Python HMAC-SHA256 Mismatch -


based on recent feedback , findings on problem, i've rewritten question rid of noise.

i have 2 separate code paths, 1 in java (android), 1 , python accomplish following purposes of negotiating pairing between android device , python/django.

java:

  • generate synckey
  • hash concatenated string of various values using presharedkey (including synckey)
  • encrypt synckey using presharedkey
  • send hash, encrypted synckey, deviceid , arbitrary variables web server

python

  • get presharedkey deviceid
  • decrypt encrypted synckey
  • hash concatenated string of various values using presharedkey (including decrypted synckey)
  • make sure hash matches, confirms synckey decrypted successfully, , deviceid holds correct presharedkey.

now process works if send synckey unencrypted. final hash matches, proves deviceid has correct preshared-key, add en/decryption process, hash no longer matches, despite fact both synckey , concatenated string appear match character character debug output of both java/python.

one quirk of process 256bit key necessary aes256 encryption algorithm, i'm chopping 512bit presharedkey in half. alternative of using 256bit key across board requiring pass key through encode('ascii') on python side, or else throwing errors during hashing shorter key.

here relevant code:

java:

string presharedkey = getkey(); // f8250b0d5960444e4de6ecc3a78900bb941246a1dece7848fc72b90092ab3ecd0c1c8e36fddba501ef92e72c95b47e07f98f7fd9cb63da75c008a3201124ea5d  string deviceid = getdeviceid(); // 1605788742789230  synckey synckey = generatesynckey(); // 824c1ee9ef507b52ea28362c71bd4ad512a5f82acfae80def531f73ac124ca814ba30ce805a157d6adb9ec04fc99aae6fdc4238fcd76b87ce22bc2fe33b2e5c9  string concat = synckey.hexstring(); // 824c1ee9ef507b52ea28362c71bd4ad512a5f82acfae80def531f73ac124ca814ba30ce805a157d6adb9ec04fc99aae6fdc4238fcd76b87ce22bc2fe33b2e5c9  string algorithm = "hmacsha256"; string hash = null; try {     secretkeyspec keyspec = new secretkeyspec(         presharedkey.getbytes(),         algorithm);     mac mac = mac.getinstance(algorithm);     mac.init(keyspec);     byte[] result = mac.dofinal(concat.getbytes());     hash = base64.encodetostring(result, base64.default);     // fpde2jlmcbr+/rw+n/jbhh13f8av80sum2fqay2iprs= } catch (nosuchalgorithmexception x) { } catch (invalidkeyexception x) { }  string enckey = presharedkey.substring(0, presharedkey.length() / 2); // f8250b0d5960444e4de6ecc3a78900bb941246a1dece7848fc72b90092ab3ecd  int len = enckey.length(); byte[] enckeybytes = new byte[len / 2]; (int = 0; < len; += 2) {     enckeybytes[i / 2] = (byte) ((character.digit(enckey.charat(i), 16) << 4)             + character.digit(enckey.charat(i+1), 16)); }  string encryptedsynckey = null; try {     byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };     algorithmparameterspec ivspec = new ivparameterspec(iv);     secretkeyspec enckeyspec = new secretkeyspec(enckeybytes, "aes");     cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding");     cipher.init(cipher.encrypt_mode, enckeyspec, ivspec);     byte[] encryptedsynckeybytes = cipher.dofinal(synckey.hexstring().getbytes());     encryptedsynckey = base64.encodetostring(encryptedsynckeybytes, base64.default);     /*         yrl0/sutuutc6oj8o4tcoy65ewo0jzoxfei9klq0aolf6rh+nn7+bec0s5ue7tio1uljb/dvr2ca         acmqvxxhgpzutb4sq0eso+t32lg0eeb9xki5cz4l9qo5raw0xbn7r/tfidvm8aifkn9qccths0df         kh3owhpwns+tfeuiblpggqp/zgtozmido9u9lb4n     */ } catch (invalidalgorithmparameterexception e) { } catch (nosuchalgorithmexception e) { } catch (nosuchpaddingexception e) { } catch (invalidkeyexception e) { } catch (illegalblocksizeexception e) { } catch (badpaddingexception e) { }  sendstufftoweb(encryptedsynckey, deviceid, hash); 

python:

hash = gethash(request) # hash java: fpde2jlmcbr+/rw+n/jbhh13f8av80sum2fqay2iprs=  encrypted_sync_key = getencsynckey(request) # encryptedsynckey java: # yrl0/sutuutc6oj8o4tcoy65ewo0jzoxfei9klq0aolf6rh+nn7+bec0s5ue7tio1uljb/dvr2ca # acmqvxxhgpzutb4sq0eso+t32lg0eeb9xki5cz4l9qo5raw0xbn7r/tfidvm8aifkn9qccths0df # kh3owhpwns+tfeuiblpggqp/zgtozmido9u9lb4n  device_id = getdeviceid(request) # 1605788742789230  preshared_key = getpresharedkeyfromdevice(deviceid) # f8250b0d5960444e4de6ecc3a78900bb941246a1dece7848fc72b90092ab3ecd0c1c8e36fddba501ef92e72c95b47e07f98f7fd9cb63da75c008a3201124ea5d  enc_key = preshared_key[:len(preshared_key)/2] # f8250b0d5960444e4de6ecc3a78900bb941246a1dece7848fc72b90092ab3ecd  aes = aes.new(enc_key.decode('hex'), aes.mode_cbc, iv="\x00"*16) sync_key = aes.decrypt(base64.b64decode(encrypted_sync_key)) # 824c1ee9ef507b52ea28362c71bd4ad512a5f82acfae80def531f73ac124ca814ba30ce805a157d6adb9ec04fc99aae6fdc4238fcd76b87ce22bc2fe33b2e5c9  concat = sync_key # 824c1ee9ef507b52ea28362c71bd4ad512a5f82acfae80def531f73ac124ca814ba30ce805a157d6adb9ec04fc99aae6fdc4238fcd76b87ce22bc2fe33b2e5c9  import hashlib hmac import new hmac  verify_hash = hmac(preshared_key, concat, hashlib.sha256).digest().encode('base64') # iosc2w2sq4/fwhjtduqhw/hdyjy+ranzq1z3j5lfyba= 

from debug output below can see synckey encrypted , decrypted successfully, , concat identical. resulting hash ends being different.

your python code wrong. can reproduce, in python, answer got in java.

if use inputs:

>>> preshared_key_hex b'f8250b0d5960444e4de6ecc3a78900bb941246a1dece7848fc72b90092ab3ecd0c1c8e36fddba501ef92e72c95b47e07f98f7fd9cb63da75c008a3201124ea5d' >>> concat_hex b'824c1ee9ef507b52ea28362c71bd4ad512a5f82acfae80def531f73ac124ca814ba30ce805a157d6adb9ec04fc99aae6fdc4238fcd76b87ce22bc2fe33b2e5c9' 

i same value in java:

>>> base64.b64encode(hmac.new(preshared_key_hex, concat_hex, hashlib.sha256).digest()) b'fpde2jlmcbr+/rw+n/jbhh13f8av80sum2fqay2iprs=' 

however, value wrong. should hex decoding input values.

i'm unable reproduce got in python; 1 of values you're passing hmac.new isn't think is. print them before calling hmac.new , should see doesn't match.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -