.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/crypto/hashing/plot_03_hmac.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_crypto_hashing_plot_03_hmac.py: HMAC: keyed hashing that resists length extension (1996) ======================================================== Bellare, Canetti and Krawczyk defined HMAC to turn any Merkle-Damgard hash into a message authentication code with a security proof: HMAC(k, m) = H((k XOR opad) || H((k XOR ipad) || m)). The outer hash hides the inner chaining state, so an attacker has nothing to extend. What to look for ---------------- The length-extension forgery that defeats the naive H(key || message) fails against HMAC. HMAC also appears inside RFC 6979's deterministic nonces and in key derivation (HKDF). The history behind this experiment: :doc:`/history/crypto_breakthroughs`. .. GENERATED FROM PYTHON SOURCE LINES 21-23 Same attack, two MACs --------------------- .. GENERATED FROM PYTHON SOURCE LINES 23-38 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk secret = b"server-side key!" order = b"user=alice&amount=10" suffix = b"&amount=1000000" results = {} for name, mac in (("naive H(k||m)", bk.crypto.naive_mac), ("HMAC", bk.crypto.hmac_sha256)): tag = mac(secret, order) glue, forged = bk.crypto.length_extension(tag, len(secret) + len(order), suffix) results[name] = forged == mac(secret, order + glue + suffix) print(f"{name}: forgery {'accepted' if results[name] else 'rejected'}") assert results == {"naive H(k||m)": True, "HMAC": False} .. rst-class:: sphx-glr-script-out .. code-block:: none naive H(k||m): forgery accepted HMAC: forgery rejected .. GENERATED FROM PYTHON SOURCE LINES 39-41 A known test vector ------------------- .. GENERATED FROM PYTHON SOURCE LINES 41-44 .. code-block:: Python tag = bk.crypto.hmac_sha256(b"key", b"The quick brown fox jumps over the lazy dog") assert tag.hex().startswith("f7bc83f430538424b13298e6aa6fb143") .. GENERATED FROM PYTHON SOURCE LINES 45-47 Changing one key bit changes about half the tag bits ---------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 47-65 .. code-block:: Python base = bk.crypto.hmac_sha256(secret, order) flips = [] for bit in range(len(secret) * 8): key = bytearray(secret) key[bit // 8] ^= 1 << (bit % 8) flips.append(bk.crypto.hamming_distance(base, bk.crypto.hmac_sha256(bytes(key), order))) assert 110 < sum(flips) / len(flips) < 146 fig, ax = plt.subplots(figsize=(7, 3.5)) ax.hist(flips, bins=15, color="#16a34a", edgecolor="white") ax.axvline(128, color="black", linestyle="--", label="half of 256 bits") ax.set( xlabel="tag bits changed by one key-bit flip", ylabel="key bits", title="An HMAC tag depends on every key bit", ) ax.legend() fig.tight_layout() .. image-sg:: /api/gallery/crypto/hashing/images/sphx_glr_plot_03_hmac_001.png :alt: An HMAC tag depends on every key bit :srcset: /api/gallery/crypto/hashing/images/sphx_glr_plot_03_hmac_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 66-71 Exercise -------- Would H(m || k), with the key at the end, resist length extension? What property of the hash would it then rely on instead? (Hint: think of collisions in m.) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.137 seconds) .. _sphx_glr_download_api_gallery_crypto_hashing_plot_03_hmac.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/crypto/hashing/plot_03_hmac.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_hmac.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_hmac.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_hmac.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_