Tải bản đầy đủ - 0 (trang)
11-19. Encrypt and Decrypt Data Using the Data Protection API

11-19. Encrypt and Decrypt Data Using the Data Protection API

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


How It Works

Given that the .NET Framework provides you with well-tested implementations of the most widely used

and trusted encryption algorithms, the biggest challenge you face when using cryptography is key

management, namely the effective generation, storage, and sharing of keys to facilitate the use of

cryptography. In fact, key management is the biggest problem facing most people when they want to

securely store or transmit data using cryptographic techniques. If implemented incorrectly, key

management can easily render useless all of your efforts to encrypt your data.

DPAPI provides encryption and decryption services without the need for you to worry about key

management. DPAPI automatically generates keys based on Windows user credentials, stores keys

securely as part of your profile, and even provides automated key expiry without losing access to

previously encrypted data.

■ Note DPAPI is suitable for many common uses of cryptography in Windows applications, but will not help you in

situations that require you to distribute or share secret or public keys with other users.

The .NET Framework contains two classes in System.Security.dll that provide easy access to the

encryption and decryption capabilities of DPAPI: ProtectedData and ProtectedMemory. Both classes allow

you to encrypt a byte array by passing it to the static method Protect, and decrypt a byte array of

encrypted data by passing it the static method Unprotect. The difference in the classes is in the scope

that they allow you to specify when you encrypt and decrypt data.

■ Caution You must use ProtectedData if you intend to store encrypted data and reboot your machine before

decrypting it. ProtectedMemory will be unable to decrypt data that was encrypted before a reboot.

When you call ProtectedData.Protect, you specify a value from the enumeration

System.Security.Cryptography.DataProtectionScope. The following are the possible values:

CurrentUser, which means that only code running in the context of the current

user can decrypt the data

LocalMachine, which means that any code running on the same computer can

decrypt the data

When you call ProtectedMemory.Protect, you specify a value from the enumeration

System.Security.Cryptography.MemoryProtectionScope. The possible values are as follows:

CrossProcess, which means that any code in any process can decrypt the

encrypted data

SameLogon, which means that only code running in the same user context can

decrypt the data




SameProcess, which means that only code running in the same process can

decrypt the data

Both classes allow you to specify additional data (entropy) when you encrypt your data. Entropy

makes certain types of cryptographic attacks less likely to succeed. If you choose to use entropy when

you protect data, you must use the same entropy value when you unprotect the data. It is not essential

that you keep the entropy data secret, so it can be stored freely without encryption.

The Code

The following example demonstrates the use of the ProtectedData class to encrypt a string entered at the

console by the user. Note that you need to reference the System.Security.dll assembly.

using System;

using System.Text;

using System.Security.Cryptography;

namespace Apress.VisualCSharpRecipes.Chapter11


class Recipe11_19


public static void Main()


// Read the string from the console.

Console.Write("Enter the string to encrypt: ");

string str = Console.ReadLine();

// Create a byte array of entropy to use in the encryption process.

byte[] entropy = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

// Encrypt the entered string after converting it to

// a byte array. Use LocalMachine scope so that only

// the current user can decrypt the data.

byte[] enc = ProtectedData.Protect(Encoding.Unicode.GetBytes(str),

entropy, DataProtectionScope.LocalMachine);

// Display the encrypted data to the console.

Console.WriteLine("\nEncrypted string = {0}",


// Attempt to decrypt the data using CurrentUser scope.

byte[] dec = ProtectedData.Unprotect(enc,

entropy, DataProtectionScope.CurrentUser);

// Display the data decrypted using CurrentUser scope.

Console.WriteLine("\nDecrypted data using CurrentUser scope = {0}",





// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter.");








C H A P T E R 12


Unmanaged Code Interoperability

The Microsoft .NET Framework is an extensive platform. However, despite having reached version 4.0, it

still does not duplicate all the features that are available in unmanaged code. Currently, the .NET

Framework does not include every function that is available in the Win32 API, and many businesses use

proprietary solutions that they have built in native code or as COM or ActiveX components.

Fortunately, the .NET Framework is equipped with interoperability features that allow you to use

native code from .NET Framework applications as well as access .NET assemblies as though they were

COM components. The recipes in this chapter describe how to do the following:

Call functions defined in a DLL, get the handles for a control or window, invoke an

unmanaged function that uses a structure, invoke unmanaged callback functions,

and retrieve unmanaged error information (recipes 12-1 through 12-5)

Use COM components from .NET Framework applications, release COM

components, and use optional parameters (recipes 12-6 through 12-8)

Use ActiveX controls from .NET Framework applications (recipe 12-9)

Expose the functionality of a .NET assembly as a COM component (recipe 12-10)

■ Note The web site PInvoke.net (http://pinvoke.net) is an invaluable resource when trying to use PInvoke to

call Win32 API functions. It provides predefined method signatures for most if not all of the Win32 API functions, as

well as usage examples and tips for many of the functions.

12-1. Call a Function in an Unmanaged DLL


You need to call a function exported by a native DLL. This function might be a part of the Win32 API or

your own native code library.





Declare a method in your C# code that you will use to access the unmanaged function. Declare this

method as both extern and static, and apply the attribute System.Runtime.InteropServices.

DllImportAttribute to specify the DLL file and the name of the unmanaged function.

How It Works

To use a native function contained in an external library, all you need to do is declare a method with the

appropriate signature—the Common Language Runtime (CLR) automatically handles the rest, including

loading the DLL into memory when the function is called and marshaling the parameters from .NET

data types to native data types. The .NET service that supports this cross-platform execution is named

PInvoke (Platform Invoke), and the process is usually seamless. Occasionally, you will need to do a little

more work, such as when you need to support in-memory structures, callbacks, or mutable strings.

PInvoke is often used to access functionality in the Win32 API, particularly Win32 features that are

not present in the set of managed classes that make up the .NET Framework. Three core libraries make

up the Win32 API:

Kernel32.dll includes operating system–specific functionality such as process

loading, context switching, and file and memory I/O.

User32.dll includes functionality for manipulating windows, menus, dialog

boxes, icons, and so on.

GDI32.dll includes graphical capabilities for drawing directly on windows, menus,

and control surfaces, as well as for printing.

As an example, consider the Win32 API functions used for writing and reading INI files, such as

GetPrivateProfileString and WritePrivateProfileString, in Kernel32.dll. The .NET Framework does

not include any classes that wrap this functionality. However, you can import these functions using the

attribute DllImportAttribute, like this:

[DllImport("kernel32.DLL", EntryPoint="WritePrivateProfileString")]

private static extern bool WritePrivateProfileString(string lpAppName,

string lpKeyName, string lpString, string lpFileName);

The arguments specified in the signature of the WritePrivateProfileString method must match the

DLL method or a runtime error will occur when you attempt to invoke it. Remember that you do not

define any method body, because the declaration refers to a method in the DLL. The EntryPoint portion

of the attribute DllImportAttribute is optional in this example. You do not need to specify the

EntryPoint when the declared function name matches the function name in the external library.

The Code

The following is an example of using some Win32 API functions to get INI file information. It declares the

unmanaged functions used and exposes public methods to call them. (Other Win32 API functions for

getting INI file information not shown in this example include those that retrieve all the sections in an

INI file.) The code first displays the current value of a key in the INI file, modifies it, retrieves the new

value, and then writes the default value.



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

11-19. Encrypt and Decrypt Data Using the Data Protection API

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