Confidential data should be secu~ so that it cannot be read by unprivileged users. This is valid both for data that is sent across the network, or data that is stored somewhere. You can encrypt such data with symmetric or symmetric encryption keys.

With a symmetric key, the same key can be used for encryption and decryption. With asymmetric encryption, different keys are used for encryption and decryption: a public and a private key. Something encrypted using a public key can be decrypted with the corresponding private key. This also works the other way around: something encrypted using a private key can be decrypted by using the corresponding public key but not the private key.

Public and private keys are always created as a pair. The public key. can be made available to everybody, and it can even be put on a Web site, but the private key must be safely locked away. Following are some examples where these public and private keys are used to explain encryption.

If Alice sends ilamessage to Bob (see Figure 20-2), and Alice wants to make sure that no one else but Bob can read the message, she uses Bob’s public key. The message is encrypted using Bob’s public key. Bob opens the message and can decrypt it using his secretly stored private key. This key exchange guarantees that no one but Bob can read Alice’s message.

There is one problem left: Bob can’t be sure that the mail comes from Alice. Eve can use Bob’s public key to encrypt messages sent to Bob and pretend to be Alice. We can extend this principle using publici private keys. Let’s start again with Alice sending a message to Bob. Before Alice encrypts the me!isage using Bob’s public key, she adds her signature and encrypts the signature using her own private key. Then she encrypts the mail using Bob’s public key. Therefore, it is guaranteed that no one else but Bob can read the mail. When Bob decrypts the message, he detects an encrypted signature. The signature can be decrypted using Alice’s public key. For Bob, it is not a problem to access Alice’s public key because the key is public. After decrypting the signature, Bob can be sure that it was Alice who sent the message. The encryption and decryption algorithms using symmetric keys are a lot faster than’ using asymmetric keys. The problem with symmetric keys is that the keys must be exchanged in a safe manner. With network communication, one way to do this is by using asymmetric keys first for the key exchange, and then symmetric keys for encryption of the data that is sent aCl’OSSthe wire.

With the .NET Framework, you find classes for encryption in the namespace System. Securi ty .Cryptography. Several symmetric and asymmetric algorithms are implemented. You can find differen algorithm classes for many different purposes. Some of the new classes with .NET 3.5 have a Cngprefix

or suffix. Cng is short for Cryptography Next Generation, which can be used with Windows Vista and Wmdows Server 2008. This API makes it possible to write a program independent of the algorithm by using a provider-based model. If you are targeting Windows Server 2003 as well, you need to pay attention to what encryption classes touse.

The following table lists encryption classes from the namespace System. Securi ty. Cryptography and their purposes. The classes without a Cng, Mdnaged, or CryptoServiceProvider suffix are abstract base classes, such as MDS.The Managed suffix means this algorithm is implemented with managed code: other classes might wrap native Windows API calls. The suffix CryptoServiceProvider is used with classes that implement the abstract base class. The Cng suffix is used with classes tharmake use of the new Cryptography CNG API that is available only with Windows Vista and Windows Server 200S.

Let’s get into examples of how these algorithms can be used programmatically.

**Signatilre**

The first example demonstrates a signature using the ECDSA algorithm for signing. Alice creates a signature-that is encrypted with her private key and can be accessed using her public key. This way, it is guaranteed that the signature is from Alice. First, take a look at the major sfeps in the Main () method: Alice’s keys are created, and the string Alice is signed and finally verified if the signature is really from Alice by using the public key. The message that is signed is converted to a byte array by using the Encoding class. To write the encrypted signature to the console, the byte array that contains the signature is converted to a string with the method convert.T6~ase64String().

Never convert encrypted data to a string using the Encoding class. The Encoding class verifies and converts invalid values that are not allowed with Unicode, and thus converting the string back to a byte array yield’s a different result. ‘

.

using System; .

using System.Security.Cryptography;

using System.Text;

namespace Wrox.ProCSharp.Security

{

class Program,

{

internal static CngKey aliceKeySignature;

CreateKeys () is the method that creates a new key pair for Alice. This key pair is stored in a static field so it can be accessed from the other methods. The Create () method of CngKey gets the algorithm as an argument to define a key pair for the algorithm. With the Export () method, the public key of the key pair is exported. This public key can be given to Bob for the verification of the signature. Alice keeps the private key. Instead of creating a key pair with the CngKey class, you can open existing keys that are stored in the key store. Usually Alice would have a certificate containing a key pair in her private store, and the store could be accessed with CngKey .Open ().

With the key pair, Alice can create the signature using the ECDsaCng class. The constructor of this class receives the CngKey from Alice that contains both the public and private key. The private key is used, signing the data with the SignDaca () method.

For verification if the signature was really from Alice, Bob checks the signature by using the public key from Alice. The byte array containing the public key blob can be imported to a CngKey object with the static Import () method. The ECDsaCng class is then used to verify the signature by invoking VerifyData ().

**Key Ex~hange and Secure Transfer**

Let’sget into a more complex example to exchange a symmetric key for a secure transferby using the DiffieHellman algorithm. In the Main () method, you can see the main functionality.Alice createsan encypted message and sends the encrypted message to Bob. Before that,key pairs are created forAlice and Bob. Bob gets access only to Alice’spublic key, and Alice gets access only to Bob’s public key.

using System;

using System.IO;

using System. Security. Cryptography;

using System. Text;

In the implementation of the CreateKeys () method, keys are created to be used with the EC Diffie Hellman 256 algorithm.

In the m~thoo AlicesendsData (), the string that contains textcharacters isconverted to a byte array by ustng the Encoding class.An ECDiffieHellmanCng object iscreated and initializedwith the key pair from Alice.Alice creates a symmetric key by using her key pair and the public key from Bob calling the method DeriveKeyMaterial (). The returned symmetric key isused with the symmetric algorithm AES to encrypt the data.AesCryptoServiceProvider requires the key and an initializationvector (IV). The IV.isgenerated dynamically from the method GenerateIV ().The symmetric key isexchanged with the help of the EC DiffieHellman algorithm, but the IV must also be exchanged. From the security standpoint, itisokay to transfer the IV unencrypted across the network – just the key exchange must be secured. The IV isstored as firstcontent in the memory stream followed by the encrypted data where the CryptoStream classuses the encryptor created by the AesCryptoServiceProvider class.Before the encrypted data isaccessed from the memory stream, the crypto stream must be closed. Otherwise, end bitswould be missing from the encrypted data.

Bob receives encrypted data in the argument of the method BobReceivesData (). First, the unencrypted initialization vector must be read. The BlockSize property of the class . AesCryptoServiceProvider returns the number of bits for a block. The number of bytes can becalculated by doing a divide by 8, and the fastest way to do this is by doing a bit shift of 3 bits. Shifting by 1 bit is a division by 2, 2 bits by 4, and 3 bits by 8. With the for loop, the first bytes of the raw bytes that contain the IV unencrypted are written to the array iv. Next, an ECDiffieHellmanCng object isinstantiated.with the key pair from Bob. Using the public key from Alice, the symmetric key is returned from the method Deri veKeyMaterial ( ) . Comparing the symmetric keys created from Alice and Bobshows that the same key value gets created. Using this’ symmetric key and the initialization vector, the message from Alice can be decrypted with the AesCryptoServiceProvider class.

When you run the application you can see similar output on the console. The message from Alice is encrypted, and decrypted by Bob with the securely exchanged symmetric key.

Alice sends message: secret message

Alice creates this symmetric key with Bobs public key information:

5NWat8AemzFCYolllae9S3Vn4AXyai4aL8ATFo41vbw=

Alice: message is encrypted: 3C5U9CpYxnoFTk3Ew2VOT5PoOJgryc5R7Te8ztau5NO=

Bob receives encrypted message

Bob creates this symmetric key with Alices public key information:

5NWat8AemzFCYolllae9S3Vn4AXyai4aL8ATFo41vbw=

Bob decrypts message to: secret message