Authenticate a message



  • Hi everyone

    How I can authenticate that a message is coming from the right source using micropy module or any pycom library?



  • @g0hww and @jcaron thank you so much for sharing.



  • @jcaron Well, I need stuff that fits in a LoRa payload. Furthermore, the wikipedia page says:

    In 2011 an informational RFC 6151[13] 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".

    Obviously YMMV.



  • @g0hww @mthethwansm

    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, darren.long@mac.com
    # 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.


Log in to reply
 

Pycom on Twitter