510 likes | 631 Views
The System.Security.Cryptography Namespace. Abdulla Alasaadi. Overview. Introduction Classes and Interfaces AsymmetricAlgorithm Class [RSA class] Digital Signature Algorithms [DSA class] HashingAlgorithems Class SymmetricAlgorithm Class. Introduction.
E N D
The System.Security.Cryptography Namespace Abdulla Alasaadi
Overview • Introduction • Classes and Interfaces • AsymmetricAlgorithm Class [RSA class] • Digital Signature Algorithms [DSA class] • HashingAlgorithems Class • SymmetricAlgorithm Class
Introduction • The System.Security.Cryptography namespace provides support for managing cryptographic hash codes, data encryption, and digital signatures. • The classes form a framework that can be extended easily to incorporate new algorithms.
Classes and Interfaces in the System.Security.Cryptography Namespace
AsymmetricAlgorithm Class • An asymmetric algorithm is one where the sender and the recipient do not share the same knowledge (i.e. only one party knows the secret key). • All asymmetric algorithm implementation classes inherit from this abstract class. • Implementations are instantiated using the Create( ) method, which accepts the name of an implementation as a String argument; the default implementation class is created if no name is specified; the system administrator determines the default class. • [subclasses: DSA, RSA]
The RSA class • The RSA class is the abstract representation of the RSA algorithm and extends AsymmetricAlgorithm. • This class provides the common functionality shared by any implementation of the underlying algorithm and allows the algorithm to be employed without regard to the implementation details
The RSACryptoServiceProvider Class • This class is the only asymmetric encryption implementation class contained in the .NET Framework. Members of the RSACryptoServiceProvider class
Encrypting and Decrypting Data using System; using System.Security.Cryptography; using System.Text; class RSAExample { static void Main( ) { // define the plaintext to encrypt byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security"); // create an instance of the RSA algorithm RSACryptoServiceProviderx_alg = new RSACryptoServiceProvider( ); // encrypt the plaintext using OAEP padding byte[] x_ciphertext =x_alg.Encrypt(x_plaintext, true); // decrypt the plaintext byte[] x_new_plaintext= x_alg.Decrypt(x_ciphertext, true); // reconstruct a string from the new plaintext and print it out string x_output = Encoding.Default.GetString(x_new_plaintext); Console.WriteLine(x_output); } }
Digital Signature Algorithms • The .NET Framework groups encryption and digital signature algorithms together as subclasses of the AsymmetricAlgorithm class. • The abstract System.Security.Cryptography.DSA class defines the CreateSignature method which accepts a SHA-1 hash code that will be PK#1 formatted and signed, as the following:
DSA Class • This class extends AsymmetricAlgorithm and is the abstract representation of the Digital Signature Algorithm (DSA). Individual implementations of DSA will extend this class. • The .NET Framework class library includes the DSACryptoServiceProvider class, which is the default implementation of the algorithm. • DSA key pairs are represented by the DSAParameters structure, and can be imported and exported from the DSA class with the ImportParameters( ) and ExportParameters( ) methods. • The CreateSignature( ) method produces a digital signature for a cryptographic hash code, which can be verified using the VerifySignature( ) method.
System.Security.Cryptography.DSA class // create the plaintext byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security"); // create the SHA-1 algorithm instance and create a hash code for the plaintext SHA1 x_sha = SHA1.Create( ); byte[] x_hashcode = x_sha.ComputeHash(x_plaintext); // create an instance of the DSA algorithm using // the Create method in the abstract class DSA x_dsa = DSA.Create( ); // use the CreateSignature method to sign the // SHA-1 hashcode created from the plaintext byte[] x_signature = x_dsa.CreateSignature(x_hashcode);
The VerifySignature method is the counterpart to CreateSignature, and accepts a SHA-1 hash • code and the signature to verify, both expressed as an array of bytes. The Example in the next slide demonstrates how to verify a DSA signature:
Example: verify a DSA signature // create the plaintext byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security"); // define the signature to verify byte[] x_signature = new Byte[] {0x7D, 0x2B, 0xD7, 0x3D, 0x88, 0xCB, 0x1B, 0x6B, 0x04, 0x62, 0x95, 0xBE, 0x28, 0x59, 0x3E, 0xC5, 0x40, 0xDA, 0x79, 0xFE, 0x3B, 0x25, 0x08, 0x4B, 0x27, 0xF1, 0x31, 0x2A, 0x6F, 0x7C, 0x6E, 0x35, 0x45, 0x9A, 0x49, 0x4C, 0xA4, 0x5E, 0xE6, 0xA0}; // create the SHA-1 algorithm instance and // create a hash code for the plaintext SHA1 x_sha = SHA1.Create( ); byte[] x_hashcode = x_sha.ComputeHash(x_plaintext); // create an instance of the DSA algorithm using // the Create method in the abstract class DSA x_dsa = DSA.Create( ); // use the VerifySignature method to verify the DSA signature boolx_signature_valid = x_dsa.VerifySignature(x_hashcode, x_signature); The VerifySignature method returns true if the signature can be verified and falseif the signature is not valid.
DSACryptoServiceProvider • For the DSA algorithm, the SHA-1 hashing algorithm is always used to generate the hash codes. Algorithm implementation signature methods
Create and verify a signature [Example] // create the plaintext byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security"); // create an instance of the DSA implementation class DSACryptoServiceProviderx_dsa = new DSACryptoServiceProvider( ); // create a signature for the plaintext byte[] x_dsa_signature = x_dsa.SignData(x_plaintext); // verify the signature, using the plaintext boolx_dsa_sig_valid = x_dsa.VerifyData(x_plaintext, x_dsa_signature); // create an instance of the RSA implementation class RSACryptoServiceProviderx_rsa = new RSACryptoServiceProvider( ); // create an instance of the SHA-1 hashing algorithm HashAlgorithm x_sha1 = HashAlgorithm.Create("SHA1"); byte[] x_rsa_signature = x_rsa.SignData(x_plaintext, x_sha1); // verify the signature, using the plaintext boolx_rsa_sig_valid = x_rsa.VerifyData(x_plaintext, x_sha1, x_rsa_signature);
HashAlgorithm • A hash algorithm processes data to create a fixed-length string, known as a hash code. • Hash algorithms are useful because it is difficult to find two sets of data that result in the same hash code; hash algorithms are an important part of the process to create digital signatures and are used to ensure data integrity. • All hash algorithm implementations inherit from this abstract class • [Subclasses KeyedHashAlgorithm, MD5, SHA1, SHA256, SHA384, SHA512]
MD5 Class • MD stands for "Message Digest," and MD5 was the fifth such algorithm that Rivest had designed. • MD5 is the fastest hashing algorithm included in the .NET Framework, but the relatively small hash code size makes it more susceptible to brute force and birthday attacks. • This class extends HashAlgorithm and is the abstract representation of the MD5 algorithm. • Individual implementations of MD5 will extend this class. The .NET Framework class library includes the MD5CryptoServiceProvider class, which is the default implementation.
SHA-1 Class • Secure Hash Algorithm • SHA-1 is considered as a secure algorithm. • In 2001 NIST defined the SHA-256, SHA-384, and SHA-512 algorithms, named after the length of the hash code that each produces. • These new algorithms are variations of SHA-1, but are sufficiently recent that their cryptographic security remains open.
SHA1 Class • This class extends HashAlgorithm and is the abstract representation of the SHA-1 algorithm, which creates a 160-bit hash code. Individual implementations of SHA-1 extend this class. The .NET Framework class library includes the SHA1CryptoServiceProvider class, which is the default implementation
SHA1CryptoServiceProvider • This subclass of SHA1 is the default implementation of the SHA-1 algorithm • SHA256 This class extends HashAlgorithm and is the abstract representation of the SHA-256 algorithm, which creates a 256-bit hash code. • SHA384 • SHA512
Birthday Attacks • It is easier to find any shared birthday than to find a specific one. • Eve is relying on being able to create two messages that produce the same hash code, knowing that it is simpler than trying to find a match for a specific message from Alice. • Any attack along these lines is a "birthday attack." • If this kind of attack is possible in your project, then you will need to select an algorithm that creates hash codes with twice the length you might expect. • If this kind of attack is not possible, then you should select a hash code based on its actual length. • As a rule, a longer hash code will take more time to attack, but takes longer to generate.
The .NET Framework Hashing Algorithms The .NET Framework includes classes for five different hashing algorithms, although four of them are closely related, being variations of the same basic premise to create hash codes of different Length. lists the hashing algorithms available.
Hashing Algorithms • Consider how much you know about an algorithm before selecting one for use in a project. For example, although SHA-256, SHA-384, and SHA-512 have longer hash codes, MD5 and SHA-1 are tried and tested and are known to be reliable. Remember that a longer hash code does not provide greater security if the underlying algorithm is flawed.
Hashing Algorithms • The first step toward creating a hash code is to create an instance of an implementation class for the algorithm that you want to use. The simplest way of doing this is to use the name of the class directly: • SHA1Managed x_hash_alg = new SHA1Managed( ); • Another approach is to use the static HashAlgorithm.Create method to instantiate the class indirectly: • HashAlgorithmx_hash_alg = HashAlgorithm.Create("SHA1");
Mapping string values to algorithm classes If you do not supply a string as an argument to the Create method or the string is not one of the values listed in Table above, then the System.Security.Cryptography.SHA1CryptoServiceProvider algorithm will be used as a default.
Hashing Data from Memory [Example] using System; using System.Text; using System.Security.Cryptography; class StringHash { static void Main(string[] args) { // define the string that we will // create a hash code for String x_str = "Programming .NET Security"; // create a byte array from the string byte[] x_message_data = Encoding.Default.GetBytes(x_str); // create an instance of the MD5 hashing algorithm HashAlgorithmx_hash_alg = HashAlgorithm.Create("MD5"); // obtain the hash code from the HashAlgorithm by // using the ComputeHash method byte[] x_hash_code = x_hash_alg.ComputeHash(x_message_data); // print out the hash code to the console foreach (byte x_byte in x_hash_code) { Console.Write("{0:X2} ", x_byte); } } } The output from this example is: E1 62 9F C2 96 85 C3 A4 5B 94 97 57 D8 9C 65 78
Hashing Streamed Data • useful for processing data-files or for reading data from a network connection. The HashAlgorithm class contains an overloaded version of the ComputeHash method for working with streams
Hashing Streamed Data [Example] The streaming data from a file called myfile.txt, which contains the string "Programming .NET Security": using System; using System.IO; using System.Security.Cryptography; class StreamHash { static void Main(string[] args) { // create the file stream Stream x_stream = new FileStream("mydata.txt", FileMode.Open); // create an instance of the MD5 hashing algorithm HashAlgorithmx_hash_alg = HashAlgorithm.Create("MD5"); // obtain the hash code from the HashAlgorithm by // using the ComputeHash method byte[] x_hash_code = x_hash_alg.ComputeHash(x_stream); // print out the hash code to the console foreach (byte x_byte in x_hash_code) { Console.Write("{0:X2} ", x_byte); } // close the stream x_stream.Close( ); } } As you might expect, the output from the example, shown below, is the same hash code produced by our first example: E1 62 9F C2 96 85 C3 A4 5B 94 97 57 D8 9C 65 78
Validating Hash Codes • Now that you have seen how to create hash codes (playing the role of Alice), we will show you how to validate them, playing the role of Bob. Remember that Bob receives a hash code and a message from Alice. He generates his own hash code and checks that it matches the one that he received. • The ValidateHashCode method uses the other two methods to validate a hash code, taking three arguments: • The name of the algorithm that Alice used to create the hash code. • The hash code Alice created, expressed as a string of hexadecimal bytes • The message from Alice, expressed as a string
Validating Hash Codes [Example] private static boolCompareHashCodes(byte[] x_hash_code1,byte[] x_hash_code2) { // check that the hash codes are the same length if (x_hash_code1.Length == x_hash_code2.Length) { // run through the hash code and check // each value in turn for (inti = 0; i < x_hash_code1.Length; i++) { if (x_hash_code1[i] != x_hash_code2[i]) { // the byte at this location is different // in each hash code return false; } } // the hash codes are the same return true; } else { // the hash codes contain different numbers of // bytes and so cannot be the same return false; } }
Keyed Hashing Algorithms • Keyed hashing algorithms address the problem of Hacker intercepting and replacing both the message and the hash code that Alice sent to Bob. • Keyed hashing algorithms mix a secret key in with the message data blocks when creating a hash code. The recipient can validate the hash code only if he knows the secret key.
The .NET Framework class hierarchy for keyed hashing algorithms. • The KeyedHashAlgorithm class extends HashAlgorithm, adding a new property called Key, which is used to get and set the secret key as a byte array. // create the keyed hashing algorithm, using the // byte array as the constructor argument // HMACSHA1 is the default KeyedHashAlgorithmx_hash_alg = KeyedHashAlgorithm.Create("HMACSHA1"); // define the key as a string string x_key_string = " This is my secret key "; // convert the string to a byte array byte[] x_key_bytes = System.Text.Encoding.Default.GetBytes(x_key_string); // set the keyed hash algorithm key x_hash_alg.Key = x_key_bytes;
SymmetricAlgorithm Class • A symmetric algorithm is one where the sender and the recipient know the secret key. • All symmetric algorithm implementations inherit from this abstract class. • Instances of implementation classes are created using the Create( ) method, which accepts the name of an implementation as a String argument.
SymmetricAlgorithm class The SymmetricAlgorithm class allows you to configure an algorithm (select the block size, padding mode, etc.) and create instances of the classes that encrypt and decrypt data; this class, and the derived implementation classes, are not used to process data directly; The LegalKeySizes and LegalBlockSizes properties return arrays of the KeySizes class, which specify the set of key lengths and cipher block sizes supported by an implementation class
Summary of .NET symmetric encryption algorithms Data Encryption Standard (DES) The Advanced Encryption Standard (AES) Designed to extend the life of DES, Triple-DES encrypts data three times using the DES algorithm. A different 56-bit key can be used for each encryption step Rijndael (pronounced "RAIN-Dahl" or "REIN-Daal") was the winner of the U.S. Government's selection process for the AES, which is the successor to the aging DES algorithm
DES Class • This class extends SymmetricAlgorithmand is the abstract representation of the Digital Encryption Standard (DES) algorithm. Individual implementations of DES extend this class. The .NET Framework class library includes the DESCryptoServiceProvider class, which is the default implementation. • In addition to the members defined by the parent class, DES implements the IsSemiWeakKey( ) and IsWeakKey( ) methods, which determine if the selected cryptographic key results in a cipher that is easy to break.
SymmetricAlgorithm Class • The LegalKeySizes and LegalBlockSizes properties return arrays of the KeySizes class, which specify the set of key lengths and cipher block sizes supported by an implementation class. • The KeySizeand BlockSize properties get or set the current key and block lengths. • The IV and Key properties get or set the initialization vector (IV) and secret key to use for encryption or decryption. New values for these properties are created with the GenerateIV( ) and • GenerateKey( ) methods; implementation classes will automatically create a new IV and secret key. • Subclasses of the SymmetricAlgorithm class do not perform encryption and decryption directly; the CreateEncryptor( ) and CreateDecryptor( ) methods return instances of the ICryptoTransform type to which these tasks are delegated. • [subclasses: DES, RC2, Rijndael, TripleDES]
The .NET Framework class hierarchy for symmetricencryption algorithms
Examples • Create an instance is by using the Create method of the SymmetricAlgorithmclass SymmetricAlgorithmx_alg = SymmetricAlgorithm.Create("RC2"); • Configuring the Algorithm x_alg.BlockSize= 192; x_alg.KeySize = 128;
Block and Key sizes. • Each algorithm supports a different set of block and key sizes. • Inspect the valid sizes programmatically using the LegalKeySizes and LegalBlockSizes properties, which rely on the KeySizes structure. The KeySizes structure:
Encrypting and Decrypting Data • An instance of ICryptoTransform transforms plaintext to ciphertext or transforms ciphertext to plaintext; each ICryptoTransform is "one-way" and can be used only for the purpose for which it was created. • The next example demonstrates how to create transformations, using the CreateEncryptor and CreateDecryptor methods:
Example // create the encryption algorithm SymmetricAlgorithmx_alg = SymmetricAlgorithm.Create("Rijndael"); // create an ICryptoTransform that can be used to encrypt data ICryptoTransformx_encryptor = x_alg.CreateEncryptor( ); // create an ICryptoTransform that can be used to decrypt data ICryptoTransformx_decryptor = x_alg.CreateDecryptor( ); The transformations that these statements create will transform data using the key from the SymmetricAlgorithm instance; there are overloaded forms of the CreateEncryptor and CreateDecryptor classes that accept byte arrays to specify particular key value.
The CryptoStream class • Instances of the ICryptoTransform interface are not useful on their own; the .NET Framework provides the CryptoStream companion class, which is the basis for using instances of ICryptoTransform. • The CryptoStream class automatically transforms blocks of data using an ICryptoTransform. • The CryptoStream class transforms data read from a stream or written to a stream.
Encrypt data in a stream [Example] using System; using System.Security.Cryptography; using System.IO; using System.Text; class MemoryEncryptionExample { static void Main( ) { // define the message that we will encrypt string x_message = "Programming .NET Security"; // get the bytes representing the message byte[] x_plaintext = Encoding.Default.GetBytes(x_message); // create the memory stream MemoryStreamx_memory_stream = new MemoryStream( ); // create the encryption algorithm SymmetricAlgorithmx_alg = SymmetricAlgorithm.Create("RC2"); // create an ICryptoTransform that can be used to encrypt data ICryptoTransformx_encryptor = x_alg.CreateEncryptor( ); // create the CryptoStream that ties together the FileStreamand the ICryptoTransform CryptoStreamx_cryptostream = new CryptoStream(x_memory_stream, x_encryptor, CryptoStreamMode.Write); // write the plaintext out to the cryptostream x_cryptostream.Write(x_plaintext, 0, x_plaintext.Length); // close the CryptoStream x_cryptostream.Close( ); // get the ciphertext from the MemoryStream byte[] x_ciphertext = x_memory_stream.ToArray( ); // print out the cipher text bytes foreach (byte b in x_ciphertext) { Console.Write("{0:X2} ", b); } } }