How is Item HMAC calculated?
I am writing a program parsing OPVault files. I am stuck on getting Item HMAC validated. The OPVault Design doc briefly mentions it is computed over item elements and values. Since the element value type could be integer, string or base64 encoded binary. I am not clear what type should be used. I have so far tried various combinations and cannot reach the expected result. Some clarification about how to encode the values would be highly appreciated!
Python snippet of one of my attempts is pasted here:
h = hmac.new(overview_mac_key, digestmod=hashlib.sha256) for k in sorted(item.keys()): if k == 'hmac': continue h.update(bytearray(k, 'utf8')) v = item[k] if k in ['k', 'd', 'o']: v = base64.b64decode(v) elif k in ['tx', 'created', 'updated']: v = v.to_bytes(4, byteorder='little') elif k == 'uuid': v = uuid.UUID(v).bytes else: v = bytearray(v, 'utf8') h.update(v) print("{}: {}".format(k, v)) got = base64.b64encode(h.digest()) expected = item['hmac'] print('expected: {}\ngot: {}'.format(expected, got)) assert(got == expected)
Full code for parsing item 0E8D7507A1C1449D8134787D638E849A from demo.opvault is at http://pastebin.com/5Cn5HDMP
Comments
-
@lht: Thanks for reaching out. I'm sorry for the delay. I'm not an authority on this, so I've asked for help from a colleague. There's some info here in the knowledgebase regarding OPVault, but it sounds like you might not be using an Apple platform. If you're using CommonCrypto there's an example there under "Implementation". Either way we'll get back to you. :)
0 -
@lht i believe a bit of code can explain HMAC better than a 1000 words:
foreach (var item in from KeyValuePair<string, JToken> item in Json where item.Key != "hmac" orderby item.Key select item) { string value; if (item.Value.Type == JTokenType.Boolean) { value = (bool)item.Value ? "1" : "0"; } else { value = (string)item.Value; } bytes.AddRange(item.Key.ToBytesFromUtf8()); bytes.AddRange(value.ToBytesFromUtf8()); }
Hope that helps :)
0 -
@brenty, @SergeyTheAgile Surely that code explains everything! Fixed the boolean encoding and my code now works! How exciting! Thanks a lot!
0 -
hehe I'm glad Sergey was able to share some holiday cheer code with you. :chuffed:
0