Problem replacing KeyNumber.Signature type keys in the key store



Hi

I'm slightly perplexed at some behaviour of the
RSACryptoServiceProvider and how it stores keys in the key store. The
short version is that if I store a KeyNumber.Exchange type key in the
key store I can replace it. If I try the same with a
KeyNumber.Signature type key I can't. To demonstrate the problem
here's some code I wrote as the body of a Visual Studio unit test:

{
string testKeyStore = "MyTestKeyStore";
KeyNumber keyNum = KeyNumber.Signature;

CspParameters tmp_cp = new CspParameters();
tmp_cp.KeyNumber = (int)keyNum;
tmp_cp.Flags &= ~CspProviderFlags.UseMachineKeyStore;

RSACryptoServiceProvider tmp_rsa = new RSACryptoServiceProvider
(tmp_cp);
Assert.IsFalse(tmp_rsa.PersistKeyInCsp);
string tmp_key = tmp_rsa.ToXmlString(true);
tmp_rsa.Clear();

CspParameters cp = new CspParameters();
cp.KeyContainerName = testKeyStore;
cp.KeyNumber = (int)keyNum;
cp.Flags |= CspProviderFlags.UseMachineKeyStore;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
Assert.IsTrue(rsa.PersistKeyInCsp);
string key = rsa.ToXmlString(true);
rsa.Clear();

Assert.AreNotEqual(tmp_key, key);

rsa = new RSACryptoServiceProvider(cp);
rsa.FromXmlString(tmp_key);
rsa.Clear();

rsa = new RSACryptoServiceProvider(cp);
string key2 = rsa.ToXmlString(true);
rsa.Clear();

string reason = null;
if (key == key2)
reason = "The original key is still there";
else if (tmp_key != key2)
reason = "There is a third key there, so the replacement key was
never saved";

Assert.IsNull(reason, reason);
}

You will notice that I generate a temporary key, open up the keystore
then pop the key in with a call to FromXmlString(). The appears to
work fine at first. Now I open up the store again and find that the
key I placed in there was never stored. The original pre-replacement
key is still there.

If you change the second line of code to

KeyNumber keyNum = KeyNumber.Exchange;

Then the test works just fine and all the methods behave exactly as
stated in the MSDN. Is there any reason why it doesn't work with
KeyNumber.Signature keys? Is this by design (and if so why?) or is it
a bug? In case anyone is wondering, I'm using Windows XP SP3 with
VS2008 and the .NET 3.5 framework.

I've spent hours trawling the web for answers and come up empty so any
help would be greatly appreciated.

Kind Regards



Anthony Smith
.