7. The Bedrock of Cybersecurity: Cryptography 175 forming hashes are produced, so changing a transaction in an old block and then working to catch back up is impossible.5 This is similar to a technique used to defend against password cracking called key stretching. In key stretching, a string is hashed, and the resulting hash is hashed, and so on, creating a hash chain. When key stretching is used for password hashes, a hash chain may be 10,000 links long or more, and the last hash in the chain is the one stored in the authentication database. The consequence of this is that when a user inputs a password to be authenticated, the input string must be hashed the chain length number of times before it can be determined if the user entered the correct password. For a hash chain of length 10,000, this requires 10,000 times the effort to authenticate each login attempt! However, hash functions are efficient, and as we know, computers are blazingly fast, so the slowdown is not even noticed by the user—maybe it is the difference between one microsecond and one hundredth of a second—in human time, authentication still occurs “instantaneously.” But why is key stretching used? Key stretching slows down password cracking attempts by a factor of the length of the hash chain. Attackers generate a multitude of putative passwords to crack a password hash (see Section 9.2.1.1). Suppose attackers can generate one trillion hashes in one day, and the average password hash takes one trillion hash attempts to crack. Assuming this math, attackers can crack a password in a day. However, if this hash were key stretched with length 10,000, then it would require the attackers to generate 10,000 times one trillion hashes to crack the password, and this would take them 10,000 days (more than twenty-seven years)! The extra work required for key stretching imposes an asymmetrical penalty on attackers because of the volume of hashes they need to generate. 7.2.3.5 Keystream Generator Lastly, hashes can be used as a keystream generator. If two parties have a shared secret, they can use the hash of the secret as a keystream and XOR their plaintext message with it to produce ciphertext. Since hashes are relatively short and keystreams need to be long, an index number can be appended to their shared secret to produce as many keystream bits as necessary. A simple scheme is to increment the secret, e.g., SHA-256(“SECRET”), SHA-256(“SECRET1”), SHA-256(“SECRET2”), etc. Table 7.11 shows how a hash function could be used to encrypt the message attack at dawn using the word SECRET as the shared secret. 7.2.3.6 Attacks on Hash Functions There are two main attacks that can be performed on hash functions to break their collision resistance property. The first is a brute-force attack. A hash collision is guaranteed if “hash buckets plus one” hashes are generated due to the pigeonhole principle. This is the worst case scenario because it assumes that every new hash generated will fall into an empty bucket, and then once all the buckets are filled with exactly one hash, the next 5 Technically, if somebody commandeered more than 50% of the computational power of the Bitcoin network, it would be possible to revise a block and catch back up.
RkJQdWJsaXNoZXIy MTM4ODY=