07.07.2023 Views

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!