14.9 Store an Asymmetric Encryption Key Securely


Problem

You need to store an asymmetric key pair in a secure location that's easily accessible from your applications.

Solution

Rely on the key persistence functionality provided by the two asymmetric algorithm classes System.Security.Cryptography.RSACryptoServiceProvider and System.Security.Cryptography.DSACryptoServiceProvider .

Discussion

Both of the concrete asymmetric algorithm classes ” RSACryptoServiceProvider and DSACryptoServiceProvider ” wrap functionality implemented by a native cryptographic service provider (CSP), which is a component of the Win32 CryptoAPI. In addition to the obvious cryptographic services such as encryption, decryption, and digital signatures, each CSP provides a key container facility.

Key containers are storage areas for cryptographic keys that the CSP manages ; the CSP uses strong encryption and operating system security to protect the container's contents. Key containers provide applications easy access to keys without compromising the security of the keys. When invoking the cryptographic functions of a CSP, an application specifies the name of a key container and the CSP accesses the necessary keys as required. Because the keys don't pass from the CSP to the application, the application can't accidentally compromise the security of the keys.

The RSACryptoServiceProvider and DSACryptoServiceProvider classes allow you to configure their underlying CSP implementation using an instance of the class System.Security.Cryptography.CspParameters . To configure an RSACryptoServiceProvider or DSACryptoServiceProvider object to use a specific key container, you must complete the following steps:

  1. Create a new CspParameters object.

  2. Set the public field KeyContainerName of the CspParameters object to a string value representing the name of the key container to use; the string may include spaces.

  3. Create a new RSACryptoServiceProvider or DSACryptoServiceProvider object, and pass the CspParameters object as a constructor argument.

If the named key container exists within the scope of the CSP and contains the appropriate keys, the CSP will use these keys when performing cryptographic operations. If the key container or keys don't exist, the CSP automatically creates new keys. To force the CSP to store newly generated keys to the named key container, you must set the value of the PersistKeyInCsp property on the RSACryptoServiceProvider or DSACryptoServiceProvider object to true .

The LoadKeys method shown here is an excerpt from the StoreAsymmetricKeyExample.cs file provided as part of the sample code for this chapter. LoadKeys creates a new RSACryptoServiceProvider object and configures it to use a key container named MyKeys . By specifying PersistKeyInCsp = true , the algorithm automatically stores newly generated keys in the named key container.

 // A method to create an RSACryptoServiceProvider and load keys from // a named CryptoAPI key container if they exist; otherwise, the  // RSACryptoServiceProvider automatically generates new keys and  // persists them to the named key container for future use. public static void LoadKeys(string container) {     // Create a new CspParameters object and set its KeyContainerName     // field to the name of the specified container.     System.Security.Cryptography.CspParameters cspParams =          new System.Security.Cryptography.CspParameters();     cspParams.KeyContainerName = container;          // Create a new RSA asymmetric algorithm and pass the CspParameters     // object that specifies the key container details.     using (System.Security.Cryptography.RSACryptoServiceProvider rsaAlg =          new System.Security.Cryptography.RSACryptoServiceProvider(cspParams)){         // Configure the RSACryptoServiceProvider object to persist         // keys to the key container.         rsaAlg.PersistKeyInCsp = true;         // Display the public keys to the console.         System.Console.WriteLine(rsaAlg.ToXmlString(false));                  // Because the RSACryptoServiceProvider object is configured to           // persist keys, the keys are stored in the specified key container.     } } 

The RSACryptoServiceProvider and DSACryptoServiceProvider classes provide no direct method of removing key containers. To delete persisted keys, set the value of PersistKeyInCsp to false and call the Clear or Dispose method of the RSACryptoServiceProvider or DSACryptoServiceProvider object. The DeleteKeys method shown here demonstrates this technique.

 // A method to create an RSACryptoServiceProvider and clear existing // keys from a named CryptoAPI key container. public static void DeleteKeys(string container) {          // Create a new CspParameters object and set its KeyContainerName     // field to the name of the container to be cleared.     System.Security.Cryptography.CspParameters cspParams =          new System.Security.Cryptography.CspParameters();     cspParams.KeyContainerName = container;          // Create a new RSA asymmetric algorithm and pass the CspParameters     // object that specifies the key container details.     using (System.Security.Cryptography.RSACryptoServiceProvider rsaAlg =          new System.Security.Cryptography.RSACryptoServiceProvider(cspParams)){         // Configure the RSACryptoServiceProvider object not to persist         // keys to the key container.         rsaAlg.PersistKeyInCsp = false;         // Display the public keys to the console. Because we call          // Dispose() after this call, existing keys will not appear to          // change until the second time the method is called.         System.Console.WriteLine(rsaAlg.ToXmlString(false));         // As the code leaves this "using" block, Dispose is called on          // the RSACryptoServiceProvider object. Because the object is          // configured NOT to persist keys, the associated key container          // is cleared. Instead of Dispose(), calling rsaAlg.Clear() would          // have the same effect, as it indirectly calls Dispose().     } } 

The Win32 CryptoAPI supports both user key stores and machine key stores. The Windows operating system ensures that a user key store is accessible only to the user that created it, but a machine key store is accessible to any user of the machine. By default, the RSACryptoServiceProvider and DSACryptoServiceProvider classes will use a user key store. You can specify the use of the machine key store by setting the static property UseMachineKeyStore of the RSACryptoServiceProvider or DSACryptoServiceProvider class to true . This will affect all code running in the current application domain. For finer-grained control, you can set the CspParameters.Flags property to the value System.Security.Cryptography.CspProviderFlags.UseMachineKeyStore before you create your asymmetric encryption object.

Warning  

You should think about your security requirements carefully before opting to use the machine key store. The fact that any user who has access to the machine can gain access to the keys contained in the store negates most of the benefits of using asymmetric encryption.




C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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