While creating cryptographic keys or key containers repeatedly, your hard disk may get filled with lots of files and may end up filling the whole hard disk space, if not deleted.

A cryptographic service provider creates key containers for storing RSA public/private asymmetric key pairs.

Key containers are stored in the user profiles unless you specify the machine key folder.

Say you use RSACryptoServiceProvider class to create a key, save it in the user profile, and then when the RSACryptoServiceProvider instance is disposed, the keys are not deleted.

The safest pattern to follow is:

1. Create the key

2. Use the key

3. Dispose of the key

Example:

 //-------------------------------------------------------------------
  
 // Declare the handle to the key.
  
 HCRYPTKEY hKey; 
  
 //-------------------------------------------------------------------
  
 // This example assumes that a cryptographic context has been acquired, and that it is stored in hCryptProv.
  
 //---------------------------------------------------------------
  
 // Create a random session key. 
  
 if(CryptGenKey(
  
           hCryptProv, 
  
           ENCRYPT_ALGORITHM, 
  
           KEYLENGTH | CRYPT_EXPORTABLE, 
  
           &hKey))
  
 {
  
          printf("A session key has been created.\n");
  
 } 
  
  else
  
 {
  
           printf("Error during CryptGenKey.\n"); 
  
           exit(1);
  
 }
  
 //-------------------------------------------------------------------
  
 //  The key created can be exported into a key BLOB that can be
  
 //  written to a file.
  
 //  ...
  
 //  When you have finished using the key, free the resource.
  
 if (!CryptDestroyKey(hKey))
  
 {
  
           printf("Error during CryptDestroyKey.\n"); 
  
           exit(1);
  
 }

 

From managed code you can specify CspProviderFlags.UseExistingKey (Supported in .NET Framework version 3.5, 3.0, 2.0, 1.1, and 1.0). Even if you use the UseExistingKey flag, you have to specific a container name; otherwise it will generate a random container name that doesn’t exist.

Example:

 CspParameters CSPParam = new CspParameters();
  
 CSPParam.Flags = CspProviderFlags.UseExistingKey;
  
 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(CSPParam);

Or we can create key containers and use the RSACryptoServiceProvider::PersistKeyInCsp Property, which is TRUE by default.

Example:

 string KeyContainerName = "MyKeyContainer";
  
 //Create a new key and persist it in the key container.  
  
 RSAPersistKeyInCSP(KeyContainerName);
  
 //Delete the key from the key container.
  
 RSADeleteKeyInCSP(KeyContainerName);
  
 ......
  
 public static void RSAPersistKeyInCSP(string ContainerName)
  
 {
  
     try
  
     {
  
         CspParameters cspParams = new CspParameters();
  
         // Specify the container name using the passed variable.
  
         cspParams.KeyContainerName = ContainerName;
  
        //Create a new instance of RSACryptoServiceProvider to generate
  
        //a new key pair.  Pass the CspParameters class to persist the 
  
        //key in the container.  The PersistKeyInCsp property is true by 
  
        //default, allowing the key to be persisted. 
  
        RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(cspParams);
  
      }
  
      catch(CryptographicException e)
  
     {
  
         Console.WriteLine(e.Message);
  
     }
  
 }
  
 public static void RSADeleteKeyInCSP(string ContainerName)
  
 {
  
     try
  
     {
  
             CspParameters cspParams = new CspParameters();
  
             // Specify the container name using the passed variable.
  
             cspParams.KeyContainerName = ContainerName;
  
             RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(cspParams);
  
             //Explicitly set the PersistKeyInCsp property to false
  
             //to delete the key entry in the container.
  
             RSAalg.PersistKeyInCsp = false;
  
             //Call Clear to release resources and delete the key from the container.
  
             RSAalg.Clear();
  
     }
  
     catch(CryptographicException e)
  
     {
  
         Console.WriteLine(e.Message);
  
     }
  
 }

 

References:

1. https://msdn.microsoft.com/en-us/library/aa379918(VS.85).aspx

2. https://msdn.microsoft.com/en-us/library/system.security.cryptography.cspproviderflags.aspx

3. https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.persistkeyincsp.aspx