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. http://msdn.microsoft.com/en-us/library/aa379918(VS.85).aspx

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

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