Authenticate a message
How I can authenticate that a message is coming from the right source using micropy module or any pycom library?
@jcaron Well, I need stuff that fits in a LoRa payload. Furthermore, the wikipedia page says:
In 2011 an informational RFC 6151 was published to summarize security considerations in MD5 and HMAC-MD5. For HMAC-MD5 the RFC summarizes that – although the security of the MD5 hash function itself is severely compromised – the currently known "attacks on HMAC-MD5 do not seem to indicate a practical vulnerability when used as a message authentication code", but it also adds that "for a new protocol design, a ciphersuite with HMAC-MD5 should not be included".
Note that MD5 is considered "cryptographically broken and unsuitable for further use" since 2008.
SHA-1 does not fare much better.
Please refrain from using MD5 (or SHA-1) and switch to more secure hashes like SHA-256 and up. Thankfully this should be a trivial change in the above code.
@mthethwansm Yeah, here it is. Running that file does a quick test against the example result shown on wikipedia for HMAC-MD5. I have also tested it for interoperability with desktop python implementations and it seems fine.
#! /usr/bin/env python3 # Copyright 2017 Darren M Long, firstname.lastname@example.org # GPLv3 applies. import gc import uhashlib def hmac_md5(key, message): blocksize = 64 # keys longer than blocksize are shortened if len(key) > blocksize: key = md5hash(key) # keys shorter than blocksize are zero-padded elif len(key) < blocksize: key = key + b'\x00'*(blocksize - len(key)) assert len(key)==blocksize o_key_pad = sxor(b'\x5c'*blocksize, key) i_key_pad = sxor(b'\x36'*blocksize, key) inner_hash = md5hash(i_key_pad+message) outer_hash = md5hash(o_key_pad+inner_hash) gc.collect() return outer_hash def md5hash(data): m = uhashlib.md5() m.update(data) return m.digest() def sxor(s1,s2): return bytes(x ^ y for x, y in zip(s1, s2)) if __name__ == '__main__': # main tests against example here: https://en.wikipedia.org/wiki/HMAC import binascii from machine import Timer chrono = Timer.Chrono() print('testing uhmac ... ',end='') chrono.start() result = hmac_md5(b"key", b"The quick brown fox jumps over the lazy dog") chrono.stop() assert binascii.hexlify(result) == b'80070713463e7749b90c2dc24911e275' assert len(result) == 16 print('ok') duration = chrono.read() print('time taken to test code: %f secs' % duration) gc.collect()
Thanks @g0hww. I looked at HMAC it seems fine for me. Can please share your HMAC-MD5 implementation.
I'm not sure if this answer is really pertinent to your question, but I use HMAC-MD5 authentication on an AES-128 encrypted payload on my SOCK_RAW LoRa links. Both MD5 and AES-128 are supported by the hardware acceleration. Both use the same pre-shared 128-bit key. I rolled my own HMAC-MD5 implementation though.