Implementing-cryptography-using-python
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Chapter 7 ■ Message Integrity 209
'''The probability that, in k random selections from n
possibilities,
at least two selections collide.'''
return 1 - alldifferent(k,n)
print(collide(35,365))
Crafting Forgeries
The biggest failure of a MAC scheme is that a nefarious user can generate a
false message that the recipient accepts as authentic. These failures are made
possible due to the CBC-MAC/birthday paradox.
Given a particular message, how many other messages would you expect to
create message tags for before finding a collision? Imagine that you have found
two messages m1, m2 such that MAC K (m1) = MAC K (m2); then MAC K (m1 +
x) = MAC K (m2 + x). To prove that the vulnerabilities exist, a team at Google
released the first concrete collision attack against SHA-1. The team has produced
two files, shattered-1.pdf and shattered-2.pdf, that produce the same SHA-1
tag. To learn more about the attack, review shattered.io.
The Length Extension Attack
Now that you have a little insight on how collisions happen, let’s examine the
SHA-1 digest in a little more detail and then define a Python forgery for it. The
Secure Hash Algorithms are a family of cryptographic hash functions published
by the National Institute of Standards and Technology (NIST) as a U.S. Federal
Information Processing Standard (FIPS), including SHA-0, SHA-1, SHA-2, and
SHA-3. The SHA-1 is a 160-bit hash function, which is like the MD5 algorithm.
The algorithm was designed by the NSA (National Security Agency) back in the
early 1990s. All hashing algorithms, including SHA-1, produce a fixed-length
message digest. The output for SHA-1 is 20 characters no matter how long the
message was that was hashed.
In general, you should use MACs such as HMAC-SHA-256 over those that
are not cryptographically secure such as MD5 and SHA-1. One of the primary
reasons is that the plain hash functions are susceptible to length extension
attacks. Many common hash functions use the Merkle-Damgård construction,
which are built using a compression function, f, and preserve an internal state,
s, which is initialized to a defined constant. Messages are produced by applying
a compression function to the current block and current state to compute an
updated internal state; the blocks are generated in fixed-sized blocks; i.e.,
s i+1 = f(s j , b i ) . One of the consequences of this design, which allows us to exploit
it, is that if you know the hash of an n-block message, you may be able to find
the hash of longer messages by applying the compression function for each