Using Session Keys to Encrypt and Decrypt Data


To understand how to perform encryption and decryption with a session key, readers must first have a deep understanding of what session keys are, how to create them, and how to persist and share them. The session keys aren't actually used for encryption and decryption until the end of this section.

A session key is an encryption key that is shared between two parties to perform encryption and decryption or used by only a single machine for encryption and decryption. One way to derive a session key is to generate a unique password on the fly as needed. This technique was discussed in the previous section. The problem with this technique is that it doesn't provide a way to share a session key securely between two devices unless each side already knows the password. Also, if two different devices are using slightly different operating system versions, the same password can yield different session keys, so the two devices would be unable to share encrypted data.

In the previous section, which demonstrated how to perform encryption by using a password, only the handle to the session key was retained. The bytes of the actual key were never directly manipulated. Thus, it was impossible to move the session key to other machines or even to save it to the disk of the local device.

A session key is analogous to a shared private key used for encryption and decryption between two parties. Because each party has a copy of the shared session key, data encrypted by one side can be decrypted by the other. One problem that arises is how to get a shared session key on two devices in a secure fashion. If the bytes of a session key are transmitted to the remote party, an attacker who can listen to the transmission also has a copy of the session key and thus can decrypt all of the traffic that is encrypted with the session key.

CryptoAPI solves this problem by imposing strict rules on how session keys can be distributed. As seen in the previous section, getting a handle to a session key is very easy, but handles are not portable. To get the underlying bytes of a session key, developers must follow the strict rules imposed by CryptoAPI. This section examines two scenarios for acquiring a session key. The first scenario is when users want to store the bytes of the session key for use by only the same machine that created the session key in the first place. The second scenario is for when developers want to store the session key in such a way that another device can also use the session key.

Storing a Session Key for Use Only by the Device That Created It

ManagedCryptoAPI provides a simple way to store a session key in such a way that it is usable only by the same device that created it. If the bytes of the session key were moved to another device, the other device would be unable to load it.

To save a session key in such a way that it is usable only by the device that created the key using ManagedCryptoAPI , follow these steps:

  1. Acquire an instance of the ManagedCryptoAPI class.

  2. Acquire and retain a handle to a key store in a CSP by calling ManagedCryptoAPI.AcquireNamedContext or ManagedCryptoAPI.AcquireDefaultContext .

  3. Acquire and retain a handle to a new session key by calling ManagedCryptoAPI.GenerateSessionKey . Pass the handle to the key store acquired in step 2 into GenerateSessionKey .

  4. Call ManagedCryptoAPI.LocalSaveSessionKey , which returns a byte array holding the actual bytes of the session key. The third argument to LocalSaveSessionKey is a reference to an Int32 . It is set to the number of bytes in the returned array that actually contain bytes of the session key.

  5. The bytes of the session key are encrypted by the CryptoAPI before they are exported. CryptoAPI stores the information needed to decrypt and use the session key in a way not specified to outside users. Thus, only the same device can import and use the bytes of the session key that LocalSaveSessionKey returns.

  6. Store the bytes of the session key using any convenient means.

Listing 14.9 is taken from the ExportSessionKey sample application. This code follows all of the steps just outlined and drops the bytes of a session key on the file system under the name LocalSessionKey.blob .

Listing 14.9 Code from ExportSessionKey
 C# private void DropPrivateSessionKey(IntPtr in_hProvider, IntPtr in_hSessionKey,         ManagedCryptoAPI in_Crypto) {    Int32 l_SessionKeySize = 0;    // Get the bytes of the session key    byte[] l_SessionKeyBytes =    in_Crypto.LocalSaveSessionKey(in_hProvider, in_hSessionKey, ref    l_SessionKeySize);    // Store the bytes of the session key on disk    System.IO.BinaryWriter l_Writer = new BinaryWriter(new            System.IO.FileStream("\LocalSessionKey.blob",            System.IO.FileMode.CreateNew));    l_Writer.Write(l_SessionKeyBytes, 0, (int)l_SessionKeySize);    l_Writer.Close(); } // This code is used to drop the session key. ManagedCryptoAPI l_Crypto = new ManagedCryptoAPI(); IntPtr l_hProvider = IntPtr.Zero; IntPtr l_hSessionKey = IntPtr.Zero; l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART"); l_hSessionKey = l_Crypto.GenerateSessionKey(l_hProvider); DropPrivateSessionKey(l_hProvider, l_hSessionKey, l_Crypto); VB Private Sub DropPrivateSessionKey(ByVal in_hProvider As IntPtr, ByVal         in_hSessionKey As IntPtr, ByVal in_Crypto As ManagedCryptoAPI)    Dim l_SessionKeySize As Int32 = 0    ' Get the bytes of the session key    Dim l_SessionKeyBytes() As Byte = in_Crypto.LocalSaveSessionKey             (in_hProvider, in_hSessionKey, l_SessionKeySize)    If (System.IO.File.Exists("\LocalSessionKey.blob")) Then       System.IO.File.Delete("\LocalSessionKey.blob")    End If    ' Store the bytes of the session key on disk    Dim l_Writer As System.IO.BinaryWriter = New System.IO.BinaryWriter(New            System.IO.FileStream("\LocalSessionKey.blob",            System.IO.FileMode.CreateNew))    l_Writer.Write(l_SessionKeyBytes, 0, Convert.ToInt32(l_SessionKeySize))    l_Writer.Close() End Sub ' This code is used to drop the session key. Dim l_Crypto As ManagedCryptoAPI = New ManagedCryptoAPI Dim l_hProvider As IntPtr = IntPtr.Zero Dim l_hSessionKey As IntPtr = IntPtr.Zero l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART") l_hSessionKey = l_Crypto.GenerateSessionKey(l_hProvider) DropPrivateSessionKey(l_hProvider, l_hSessionKey, l_Crypto) 

Once a session key has been saved, it can be reloaded by the same device in the future and used to perform encryption and decryption. This process is discussed in the section named "Importing a Previously Saved Session into the Same Device That Created It."

The ExportSessionKey sample application located in SampleApplications\Chapter14 . There is a C# and a Visual Basic version. The application demonstrates exporting sessions keys for use by the same machine that created it and for use by other machines. To export a session key that can be imported only by the same device, click the button labeled Drop Private Session Key. The program writes the bytes of the session key into a file named LocalSessionKey.blob . The key can be imported by following the steps in the next section, "Importing a Previously Saved Session into the Same Device That Created It."

Clicking the button labeled Drop Exported Session Key writes a session key in a format that can be used by another device. The section titled "Sharing a Session Key with a Remote Device" outlines all of the steps needed to share a session key with another device. This sample application demonstrates step 4 of the "Overview of Steps for Sharing a Session Key" section.

Clicking the button labeled Drop Pair of Session Keys has the same effect as first clicking Drop Private Session Key and then clicking Drop Exported Session Key.

Importing a Previously Saved Session into the Same Device That Created It

The previous section described how to save the bytes of a session key as an array of bytes. The ManagedCryptoAPI class can easily import the session key easily from the bytes that were saved previously. Importing a session key yields a handle to an encryption key that can be used to encrypt and decrypt data. Data that was previously encrypted with the same key can be decrypted by loading the session key and using its handle to decrypt data. To import a private session key with ManagedCryptoAPI, follow these steps:

  1. Acquire an instance of the ManagedCryptoAPI class.

  2. Acquire and retain a handle to a key store in a CSP by calling ManagedCryptoAPI.AcquireNamedContext or ManagedCryptoAPI.AcquireDefaultContext .

  3. Acquire a byte array that holds the bytes of the session key to import.

  4. Call ManagedCryptoAPI.LoadPrivateSessionKey , passing in the byte array and the handle to the key store. LoadPrivateSessionKey returns a handle to an encryption key that you can use to encrypt and decrypt data.

Listing 14.10, derived from the ImportSessionKey sample application, demonstrates these steps.

Listing 14.10 ImportSessionKey
 C# ManagedCryptoAPI l_Crypto = new ManagedCryptoAPI(); IntPtr l_hProvider = IntPtr.Zero; IntPtr l_hPrivateSessionKey = IntPtr.Zero; l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART"); l_Reader = new BinaryReader(new System.IO.FileStream("\LocalSessionKey.blob",          System.IO.FileMode.Open)); byte[] l_PrivateKeyBytes = l_Reader.ReadBytes(1000); l_Reader.Close(); l_hPrivateSessionKey = l_Crypto.LoadPrivateSessionKey(l_hProvider,          l_PrivateKeyBytes); // Use l_hPrivateSessionKey for encryption and decryption VB Dim l_Crypto As ManagedCryptoAPI = New ManagedCryptoAPI Dim l_hProvider As IntPtr = IntPtr.Zero Dim l_hPrivateSessionKey As IntPtr = IntPtr.Zero l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART") ' Get the bytes of the public exchange key which we already have ' gotten from another device. Dim l_Reader As System.IO.BinaryReader = Nothing l_Reader = New System.IO.BinaryReader(New System.IO.FileStream          ("\LocalSessionKey.blob", System.IO.FileMode.Open)) Dim l_PrivateKeyBytes() As Byte = l_Reader.ReadBytes(1000) l_Reader.Close() l_hPrivateSessionKey = l_Crypto.LoadPrivateSessionKey(l_hProvider,          l_PrivateKeyBytes) ' Use l_hPrivateSessionKey for encryption and decryption 

The sample application ImportSessionKey demonstrates the end-to-end scenario of importing a private session key and using it for encryption and decryption. Because it can also import a session key exported from another device, it is discussed in detail at the end of the chapter.

Sharing a Session Key with a Remote Device

Sharing a session key with a remote device is complicated. Before jumping into the details of how to do it, this section outlines the overall steps that two devices must take in order to share a session key between them. Each step in the overall outline is covered in greater detail in this chapter, including code samples and sample applications.

Overview of Steps for Sharing a Session Key
  1. Device A generates a session key and saves it locally, as depicted in the section "Importing a Previously Saved Session into the Same Device That Created It."

  2. Device B generates a public key and saves it, as depicted in the section titled "Generating the Public Key."

  3. The saved public key is transferred from Device B to Device A.

  4. Device A "imports" the public key exchange key and uses it to save the same session key that was created in step 1. Only Device B can use the session key that is saved in this way. Saving the key this way is depicted in the section titled "Importing a Public Key Exchange Key."

  5. The saved session key from step 4 is transferred from Device A to Device B.

  6. Device B imports the saved session key that was transferred to it in step 5 and uses it for encryption and decryption. This step is depicted in the section titled "Importing a Session Key from Another Device."

  7. Device A imports the session key it generated in step 1 and uses it for encryption and decryption. This step is depicted in the section titled "Importing a Previously Saved Session into the Same Device That Created It."

  8. Device A and Device B can decrypt each other's encrypted data by using the session keys they imported in steps 6 and 7. Encrypting and decrypting data using a handle to a session key is covered in the section titled "Encrypting and Decrypting by Using a Handle to a Session Key."

Generating the Public Key

This discussion assumes there are two devices called Device A and Device B. Device A has generated a session key that it can save for its own future use as described in the section titled "Storing a Session Key for Use Only by the Device That Created It." Device A also wants to give the session key to Device B in a secure way. How does this happen?

The answer is that Device B must generate a public-private key pair. Any data encrypted with the public key exchange key can be decrypted with the corresponding private key. Device B can send the bytes of the public key to Device A, and Device A can encrypt the bytes of the session key using the public key. The encrypted session key can then go to Device B, and only Device B holds the private key capable of decrypting the session key. Thus, it would not matter if an attacker saw the encrypted session key as it was transferredit is useless without the private key.

Encryption using public-private key pairs is roughly a thousand times slower than using a shared session key. For this reason, the only support in CryptoAPI for public-private key pairs is to use them to exchange session keys safely, which are then used for encryption. There is no support in CryptoAPI for using the exported public keys to do anything but encrypt other session keys.

This section describes how to generate the public key with the help of ManagedCryptoAPI . That is, this section covers step 2 of the "Overview of Steps for Sharing a Session Key" section. To export a public key through the ManagedCryptoAPI , follow these steps:

  1. Acquire an instance of the ManagedCryptoAPI class.

  2. Acquire and retain a handle to a key store in a CSP by calling ManagedCryptoAPI.AcquireNamedContext or ManagedCryptoAPI.AcquireDefaultContext .

  3. Acquire the bytes of the public key exchange key by calling ManagedCryptoAPI.ExportPublicKey . Pass in the handle to the key store and a reference to an Int32 . ExportPublicKey returns a byte array holding the bytes of the public key exchange key and sets the Int32 to the number of bytes in the returned byte array that actually hold bytes of the public key exchange key.

Listing 14.11, derived from the ExportPublicKeyDemo sample application, acquires the bytes of the public key exchange key and dumps them into a file named PublicExchangeKey.blob :

Listing 14.11 Code will acquire bytes of the public key exchange key and dump them into a file named PublicExchangeKey.blob
 C# ManagedCryptoAPI l_Crypto = new ManagedCryptoAPI(); IntPtr l_hProvider = IntPtr.Zero; Int32  l_PubKeySize = 0; l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART"); byte[] l_PublicExchangeKeyBytes = l_Crypto.ExportPublicKey(l_hProvider,    ref l_PubKeySize); System.IO.BinaryWriter l_Writer = new BinaryWriter(new    System.IO.FileStream("\PublicExchangeKey.blob",    System.IO.FileMode.CreateNew)); l_Writer.Write(l_PublicExchangeKeyBytes, 0, (int)l_PubKeySize); l_Writer.Close(); VB Dim l_Crypto As ManagedCryptoAPI = New ManagedCryptoAPI Dim l_hProvider As IntPtr = IntPtr.Zero Dim l_PubKeySize As Int32 = 0 l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART") Dim l_PublicExchangeKeyBytes() As Byte = l_Crypto.ExportPublicKey(l_hProvider,         l_PubKeySize) If (System.IO.File.Exists("\PublicExchangeKey.blob")) Then    System.IO.File.Delete("\PublicExchangeKey.blob") End If Dim l_Writer As System.IO.BinaryWriter = New System.IO.BinaryWriter(New         System.IO.FileStream("\PublicExchangeKey.blob",         System.IO.FileMode.CreateNew)) l_Writer.Write(l_PublicExchangeKeyBytes, 0, Convert.ToInt32(l_PubKeySize)) l_Writer.Close() 
Exporting a Public Key in a Sample Application

The ExportPublicKeyDemo sample application is located in the folder \SampleApplications\ Chapter14 . There are C# and Visual Basic versions. To use the application, click the button labeled Export Public Key Exchange Key. The program uses the ManagedCryptoAPI to acquire a byte array holding the public key exchange key, and it writes the bytes to a file called PublicExchangeKey.blob . This file can be copied to another device. The other device uses it to encrypt a session key in such a way that only the first device can use it the session key. The act of exporting a session key in this way is step 4 in the "Overview of Steps for Sharing a Session Key" subsection, and it is covered in the next subsection, "Importing a Public Key Exchange Key."

Importing a Public Key Exchange Key

In the scenario where two devices, Device A and Device B, must share a session key, assume that Device A has generated a public key exchange key, that the bytes are stored in a file, and that the file has been copied to Device B. Device B must import the public key exchange key and use it to export a session key. When Device B exports the session key in this way, the session key is encrypted so that only Device A can use it. The exported session key is copied back to Device A and imported as outlined in the section titled "Importing a Session Key from Another Device."

Device B also saves a copy of the same session key that it can use itself, as outlined in the section titled "Storing a Session Key for Use Only by the Device That Created It."

The ManagedCryptoAPI class makes it easy to import a public key exchange key and use it to export a session key. To do so, follow these steps:

  1. Acquire an instance of the ManagedCryptoAPI class.

  2. Acquire and retain a handle to a key store in a CSP by calling ManagedCryptoAPI.AcquireNamedContext or ManagedCryptoAPI.AcquireDefaultContext .

  3. Generate the session key that will be exported.

  4. Acquire the bytes of the public exchange key that was generated on another device as a byte array.

  5. Import the bytes of the public key exchange key to acquire a handle to the imported key. The easiest way to do this is to call ManagedCryptoAPI.ImportPublicKey .

  6. Export the session key to another array of bytes. The easiest way to do this is to call ManagedCryptoAPI.ExportSessionKey . Pass in the handle to the public key, acquired in step 5 and the handle to the session key to export, acquired in step 3. Also pass in a reference to an Int32 . ExportSessionKey sets the Int32 to the number of bytes in the returned array that hold the bytes of the exported session key.

  7. Copy the bytes of the exported session key to the remote device through any convenient means, such as saving to a file or even transmitting over a socket connection. It is safe to do this because the session key is encrypted with the remote device's public key exchange key.

  8. The remote device now has a session key. It can import the key as depicted in the section "Importing a Session Key from Another Device."

ALSO STORE A SESSION KEY LOCALLY WHEN YOU EXPORT IT

Make sure to save this session key locally, as well, as depicted in the section titled "Storing a Session Key for Use Only by the Device That Created It," so that both devices will access the same key. Retain a handle to the session key.


Listing 14.12 illustrates steps 1 through 7.

Listing 14.12 Code that demonstrates steps 1 through 7 of importing a public key exchange key
 C# private void DropExportedSessionKey(IntPtr in_hProvider, IntPtr   in_hSessionKey, ManagedCryptoAPI in_Crypto) {    IntPtr l_PublicExchangeKey = IntPtr.Zero;    Int32 l_SessionKeySize = 0;    // Get the bytes of the public exchange key which we already have    // gotten from another device.    System.IO.BinaryReader l_Reader = new BinaryReader(new       System.IO.FileStream("\PublicExchangeKey.blob",       System.IO.FileMode.Open));    byte[] l_PublicExchangeKeyBytes = l_Reader.ReadBytes(1000);    l_Reader.Close();    l_PublicExchangeKey = in_Crypto.ImportPublicKey(in_hProvider,       l_PublicExchangeKeyBytes);    byte[] l_ExportedSessionKeyBytes =       in_Crypto.ExportSessionKey(l_PublicExchangeKey, in_hSessionKey,       ref l_SessionKeySize);    // The session key is encrypted using the public exchange key from    // the other device.    // We store the bytes of the session key on disk    if (File.Exists("\ExportedSessionKey.blob"))    {       File.Delete("\ExportedSessionKey.blob");    }    System.IO.BinaryWriter l_Writer = new BinaryWriter(new       System.IO.FileStream("\ExportedSessionKey.blob",       System.IO.FileMode.CreateNew));    l_Writer.Write(l_ExportedSessionKeyBytes, 0, (int)l_SessionKeySize);    l_Writer.Close(); } // This code will drop an exportable session key ManagedCryptoAPI l_Crypto = new ManagedCryptoAPI(); IntPtr l_hProvider = IntPtr.Zero; IntPtr l_hSessionKey = IntPtr.Zero; l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART"); l_hSessionKey = l_Crypto.GenerateSessionKey(l_hProvider); DropExportedSessionKey(l_hProvider, l_hSessionKey, l_Crypto); VB Private Sub DropExportedSessionKey(ByVal in_hProvider As IntPtr,         ByVal in_hSessionKey As IntPtr, ByVal in_Crypto As ManagedCryptoAPI)    Dim l_PublicExchangeKey As IntPtr = IntPtr.Zero    Dim l_SessionKeySize As Int32 = 0    ' Get the bytes of the public exchange key which we already have gotten    ' from another device.    Dim l_Reader As System.IO.BinaryReader = New System.IO.BinaryReader(New            System.IO.FileStream("\PublicExchangeKey.blob",            System.IO.FileMode.Open))    Dim l_PublicExchangeKeyBytes() As Byte = l_Reader.ReadBytes(1000)    l_Reader.Close()    l_PublicExchangeKey = in_Crypto.ImportPublicKey(in_hProvider,            l_PublicExchangeKeyBytes)    Dim l_ExportedSessionKeyBytes() As Byte = in_Crypto.ExportSessionKey             (l_PublicExchangeKey, in_hSessionKey, l_SessionKeySize)    ' The session key is encrypted using the public exchange key from the other    ' device. We store the bytes of the session key on disk    If (System.IO.File.Exists("\ExportedSessionKey.blob")) Then       System.IO.File.Delete("\ExportedSessionKey.blob")    End If    Dim l_Writer As System.IO.BinaryWriter = New System.IO.BinaryWriter(New            System.IO.FileStream("\ExportedSessionKey.blob",            System.IO.FileMode.CreateNew))    l_Writer.Write(l_ExportedSessionKeyBytes, 0, Convert.ToInt32             (l_SessionKeySize))    l_Writer.Close() End Sub ' This code will drop an exportable session key Dim l_Crypto As ManagedCryptoAPI = New ManagedCryptoAPI Dim l_hProvider As IntPtr = IntPtr.Zero Dim l_hSessionKey As IntPtr = IntPtr.Zero l_hProvider = l_Crypto.AcquireNamedContext("KICKSTART") l_hSessionKey = l_Crypto.GenerateSessionKey(l_hProvider) DropExportedSessionKey(l_hProvider, l_hSessionKey, l_Crypto) 
Exporting a Session Key in a Sample Application

The ExportSessionKey sample application is located in the folder \SampleApplications\ Chapter14 , with C# and Visual Basic versions in separate folders. This application can export session keys for remote devices. It can also export session keys that the same device can use later by following the steps outlined in the section titled "Importing a Previously Saved Session into the Same Device That Created It." The application first imports a public key exchange key before it exports the session key for use by another device.

To make the application export a session key by using the public key exchange key from another device, follow these steps:

  1. Run the ExportPublicKeyDemo application in another device to create a public exchange key that is stored in a file named PublicExchangeKey.blob .

  2. Copy the PublicExchangeKey.blob file to the root folder of the device that will run ExportSessionKey.

  3. Run ExportSessionKey and click the Drop Exported Session Key button. The program responds by importing the public key exchange key from the PublicExchangeKey.blob file and exporting a session key to a file named ExportedSessionKey.blob .

Importing a Session Key from Another Device

Before starting this section, it is assumed that the following has occurred between Device A and Device B:

  • Device A has created a public key exchange key and transferred it to Device B, as described in the "Generating the Public Key" section.

  • Device B has imported the public key exchange key and used it to export a session key, as described in the section titled "Importing a Public Key Exchange Key." The session key has been copied back to Device A.

SIMULTANEOUSLY DROPPING A SESSION KEY FOR LOCAL AND EXPORTED USE

You can press the Drop Pair of Session Keys button to drop both an exported session key called ExportedSessionKey.blob and a session key for use by the same device called LocalSessionKey.blob .


Device A is now ready to import the session key that has been copied to it. The act of importing the session key means that the CryptoAPI has read the bytes of the key and returned a handle to the session key. That handle can be used to perform encryption and decryption, as described in the section titled "Encrypting and Decrypting by Using a Handle to a Session Key."

ManagedCryptoAPI provides a simple means of importing the session key and acquiring a handle to the key that can be used for encryption and decryption. To do this, follow these steps:

  1. Acquire an instance of the ManagedCryptoAPI class.

  2. Acquire and retain a handle to a key store in a CSP by calling ManagedCryptoAPI.AcquireNamedContext or ManagedCryptoAPI.AcquireDefaultContext .

  3. Acquire the bytes of the session key to import into a byte array.

  4. Call ManagedCryptoAPI.LoadSharedSessionKey , passing in a handle to the key store and the byte array holding the session key to import. LoadSharedSessionKey returns a handle to the session key that can be used for encryption and decryption, as shown in the next section, "Encrypting and Decrypting by Using a Handle to a Session Key."

The following sample code is taken from the sample application ImportLocalSessionKey. It loads the bytes of the session key to import and gets a handle to it.

 
 C# l_Reader = new BinaryReader(new System.IO.FileStream          ("\ExportedSessionKey.blob", System.IO.FileMode.Open)); byte[] l_SharedKeyBytes = l_Reader.ReadBytes(1000); l_Reader.Close(); l_hPrivateSessionKey = l_Crypto.LoadSharedSessionKey(l_hProvider,         l_SharedKeyBytes); // Use l_hPrivateSessionKey for encryption and decryption VB l_Reader = New System.io.BinaryReader(New System.IO.FileStream          ("\ExportedSessionKey.blob", System.IO.FileMode.Open)) Dim l_SharedKeyBytes() As Byte = l_Reader.ReadBytes(1000) l_Reader.Close() l_hPrivateSessionKey = l_Crypto.LoadSharedSessionKey(l_hProvider,         l_SharedKeyBytes) ' Use l_hPrivateSessionKey for encryption and decryption 

Encrypting and Decrypting by Using a Handle to a Session Key

The ManagedCryptoAPI class provides a way to encrypt and decrypt data using a handle to a session key. You can get the session key in three ways:

  • Import a session key that was exported by your own device, as described in the section titled "Importing a Previously Saved Session into the Same Device That Created It."

  • Import a session key that was exported by another device, as described in the "Importing a Session Key from Another Device" section.

  • Call ManagedCryptoAPI.GenerateSessionKey directly. You can see an example of calling GenerateSessionKey by looking at the section titled "Encrypting and Decrypting by Using a Handle to a Session Key."

No matter how you got a handle to a session key, you use it in the same way to encrypt and decrypt data. To encrypt data, follow these steps:

  1. Acquire an instance of ManagedCryptoAPI .

  2. Acquire a handle to a session key by using one of the three methods described earlier.

  3. Acquire the data to encrypt as a byte array.

  4. Call ManagedCryptoAPI.KeyEncrypt , passing in the data to encrypt and the session key handle. KeyEncrypt returns an array of bytes with the encrypted data.

The following code demonstrates these steps:

 
 C# // Get the bytes to encrypt from the user interface byte[] l_PlainTextBytes = System.Text.Encoding.ASCII.GetBytes          (this.txtInitialText.Text); // l_hPrivateSessionKey holds the handle to the session key. byte[] l_Encrypted = l_Crypto.KeyEncrypt(l_hPrivateSessionKey,         l_PlainTextBytes); VB ' Get the bytes to encrypt from the user interface Dim l_PlainTextBytes() As Byte = System.Text.Encoding.ASCII.GetBytes          (Me.txtInitialText.Text) ' l_hPrivateSessionKey holds the handle to the session key. Dim l_Encrypted() As Byte = l_Crypto.KeyEncrypt(l_hPrivateSessionKey,         l_PlainTextBytes) 

To decrypt data, follow these steps:

  1. Acquire an instance of ManagedCryptoAPI .

  2. Acquire a handle to a session key using one of the three methods described earlier.

  3. Acquire the data to decrypt as a byte array.

  4. Call ManagedCryptoAPI.KeyDecrypt , passing in an array of bytes holding the data to decrypt, the session key handle, and a reference to an Int32 that holds the number of bytes in the array that was passed in and holds encrypted data. KeyDecrypt returns an array of bytes and sets the Int32 to the number of bytes in the array that holds decrypted data.

The following code demonstrates these steps:

 
 C# // l_Encrypted holds the encrypted data // l_hPrivateSessionKey holds the handle to the session key. Int32 l_TotalDecrypted = l_Encrypted.Length; byte[] l_Decrypted = l_Crypto.KeyDecrypt(l_hPrivateSessionKey, l_Encrypted,         ref l_TotalDecrypted); VB ' l_Encrypted holds the encrypted data ' l_hPrivateSessionKey holds the handle to the session key. Dim l_TotalDecrypted As Int32 = l_Encrypted.Length Dim l_Decrypted() As Byte = l_Crypto.KeyDecrypt(l_hPrivateSessionKey,         l_Encrypted, l_TotalDecrypted) 
Importing a Session Key with a Sample Application

The C# and Visual Basic versions of the ImportSessionKey sample application are located in SampleApplications\Chapter14 . This application demonstrates how to import session keys created by the same device and how to import session keys created by another device.

If you want to use a session key that was created by the same device running ImportSessionKey, then run the ExportSessionKey application to generate a file holding the bytes of the session key. Make sure that the file is named LocalSessionKey.blob on the root directory of the device. Make sure that the checkbox labeled "Use shared session key" is not checked, and then click the Go button. The sample application imports the locally created session key and uses it to encrypt the data in the textbox labeled Initial Text. Then the encrypted data is painted into the Encrypted Bytes textbox. Next it is decrypted and painted into the Decrypted Text textbox.

If you want to use a session key that was created by another device, follow these steps to use this sample application:

  1. It is assumed that Device A will run ImportSessionKey and it will import a session key from Device B.

  2. Run the ExportPublicKeyDemo sample application on Device A. This program drops a public key named PublicExchangeKey.blob for sharing session keys, as discussed in the section titled "Generating the Public Key." Copy this file to Device B.

  3. On Device B, run ExportSessionKey and click the button labeled Drop Exported Session Key. This causes Device B to export a session key encrypted with the public key from Device A. Thus, only Device A can use this encrypted version of the session key. The encrypted session key is stored in a file called ExportedSessionKey.blob . Copy this file back to Device A.

  4. Run ImportSessionKey on Device A and be sure that the checkbox labeled "Use shared session key" is checked. Click the Go button. The sample application imports the session key from Device B and uses it to encrypt the data in the textbox labeled Initial Text. Then the encrypted data is painted into the Encrypted Bytes textbox. Next it is decrypted and painted into the Decrypted Text textbox.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net