Tải bản đầy đủ - 0 (trang)
11-16. Verify a Hash Code

11-16. Verify a Hash Code

Tải bản đầy đủ - 0trang

CHAPTER 11 ■ SECURITY AND CRYPTOGRAPHY



Hash codes are often stored in text files, either as hexadecimal strings (for example,

89D22213170A9CFF09A392F00E2C6C4EDC1B0EF9) or as Base64-encoded strings (for example,

idIiExcKnP8Jo5LwDixsTtwbDvk=). Alternatively, hash codes may be stored in databases as raw byte values.

Regardless of how you store your hash code, the first step in comparing old and new hash codes is to get

them both into a common form.



The Code

This following example contains three methods that use different approaches to compare hash codes:





VerifyHexHash: This method converts a new hash code (a byte array) to a

hexadecimal string for comparison to an old hash code. Other than the

BitConverter.ToString method, the .NET Framework class library does not

provide an easy method to convert a byte array to a hexadecimal string. You must

program a loop to step through the elements of the byte array, convert each

individual byte to a string, and append the string to the hexadecimal string

representation of the hash code. The use of System.Text.StringBuilder avoids the

unnecessary creation of new strings each time the loop appends the next byte

value to the result string. (See recipe 2-1 for more details.)







VerifyB64Hash: This method takes a new hash code as a byte array and the old

hash code as a Base64-encoded string. The method encodes the new hash code as

a Base64 string and performs a straightforward string comparison of the two

values.







VerifyByteHash: This method compares two hash codes represented as byte

arrays. The .NET Framework class library does not include a method that

performs this type of comparison, and so you must program a loop to compare

the elements of the two arrays. This code uses a few time-saving techniques,

namely ensuring that the byte arrays are the same length before starting to

compare them and returning false on the first difference found.



using System;

using System.Text;

namespace Apress.VisualCSharpRecipes.Chapter11

{

class Recipe11_16

{

// A method to compare a newly generated hash code with an

// existing hash code that's represented by a hex code string.

public static bool VerifyHexHash(byte[] hash, string oldHashString)

{

// Create a string representation of the hash code bytes.

StringBuilder newHashString = new StringBuilder(hash.Length);



584



www.it-ebooks.info



CHAPTER 11 ■ SECURITY AND CRYPTOGRAPHY



// Append each byte as a two-character uppercase hex string.

foreach (byte b in hash)

{

newHashString.AppendFormat("{0:X2}", b);

}

// Compare the string representations of the old and new hash

// codes and return the result.

return (oldHashString == newHashString.ToString());

}

// A method to compare a newly generated hash code with an

// existing hash code that's represented by a Base64-encoded string.

private static bool VerifyB64Hash(byte[] hash, string oldHashString)

{

// Create a Base64 representation of the hash code bytes.

string newHashString = Convert.ToBase64String(hash);

// Compare the string representations of the old and new hash

// codes and return the result.

return (oldHashString == newHashString);

}

// A method to compare a newly generated hash code with an

// existing hash code represented by a byte array.

private static bool VerifyByteHash(byte[] hash, byte[] oldHash)

{

// If either array is null or the arrays are different lengths,

// then they are not equal.

if (hash == null || oldHash == null || hash.Length != oldHash.Length)

return false;

// Step through the byte arrays and compare each byte value.

for (int count = 0; count < hash.Length; count++)

{

if (hash[count] != oldHash[count]) return false;

}

// Hash codes are equal.

return true;

}

}

}



585



www.it-ebooks.info



CHAPTER 11 ■ SECURITY AND CRYPTOGRAPHY



11-17. Ensure Data Integrity Using a Keyed Hash Code

Problem

You need to transmit a file to someone and provide the recipient with a means to verify the integrity of

the file and its source.



Solution

Share a secret key with the intended recipient. This key would ideally be a randomly generated number,

but it could also be a phrase that you and the recipient agree to use. Use the key with one of the keyed

hashing algorithm classes derived from the System.Security.Cryptography.KeyedHashAlgorithm class to

create a keyed hash code. Send the hash code with the file. On receipt of the file, the recipient will

generate the keyed hash code of the file using the shared secret key. If the hash codes are equal, the

recipient knows that the file is from you and that it has not changed in transit.



How It Works

Hash codes are useful for comparing two pieces of data to determine if they are the same, even if you no

longer have access to the original data. However, you cannot use a hash code to reassure the recipient of

data as to the data’s integrity. If someone could intercept the data, that person could replace the data

and generate a new hash code. When the recipient verifies the hash code, it will seem correct, even

though the data is actually nothing like what you sent originally.

A simple and efficient solution to the problem of data integrity is a keyed hash code. A keyed hash

code is similar to a normal hash code (discussed in recipes 11-14 and 11-15); however, the keyed hash

code incorporates an element of secret data—a key—known only to the sender and the receiver. Without

the key, a person cannot generate the correct hash code from a given set of data. When you successfully

verify a keyed hash code, you can be certain that only someone who knows the secret key could generate

the hash code.



■ Caution The secret key must remain secret. Anyone who knows the secret key can generate valid keyed hash

codes, meaning that you would be unable to determine whether someone else who knew the key had changed the

content of a document. For this reason, you should not transmit or store the secret key with the document whose

integrity you are trying to protect.



Generating keyed hash codes is similar to generating normal hash codes. The abstract class

System.Security.Cryptography.KeyedHashAlgorithm extends the class System.Security.

Cryptography.HashAlgorithm and provides a base class from which all concrete keyed hashing algorithm

implementations must derive. The .NET Framework class library includes the seven keyed hashing

algorithm implementations listed in Table 11-5. Each implementation is a member of the namespace

System.Security.Cryptography.



586



www.it-ebooks.info



CHAPTER 11 ■ SECURITY AND CRYPTOGRAPHY



Table 11-5. Keyed Hashing Algorithm Implementations



Algorithm/Class Name



Key Size (in Bits)



Hash Code Size (in Bits)



HMACMD5



Any



128



HMACRIPEMD160



Any



160



HMACSHA1



Any



160



HMACSHA256



Any



256



HMACSHA384



Any



384



HMACSHA512



Any



512



MACTripleDES



128, 192



64



As with the standard hashing algorithms, you can either create keyed hashing algorithm objects

directly or use the static factory method KeyedHashAlgorithm.Create and pass the algorithm name as an

argument. Using the factory approach allows you to write generic code that can work with any keyed

hashing algorithm implementation, but as shown in Table 11-5, MACTripleDES supports fixed key lengths

that you must accommodate in generic code.

If you use constructors to instantiate a keyed hashing object, you can pass the secret key to the

constructor. Using the factory approach, you must set the key using the Key property inherited from the

KeyedHashAlgorithm class. Then call the ComputeHash method and pass either a byte array or a

System.IO.Stream object. The keyed hashing algorithm will process the input data and return a byte

array containing the keyed hash code. Table 11-5 shows the size of the hash code generated by each

keyed hashing algorithm.



The Code

The following example demonstrates the generation of a keyed hash code from a file. The example uses

the given class to generate the keyed hash code, and then displays it to the console. The example

requires three command-line arguments: the name of the file from which the hash is calculated, the

name of the class to instantiate, and the key to use when calculating the hash.

using

using

using

using



System;

System.IO;

System.Text;

System.Security.Cryptography;



namespace Apress.VisualCSharpRecipes.Chapter11

{

class Recipe11_17

{



587



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

11-16. Verify a Hash Code

Tải bản đầy đủ ngay(0 tr)

×