I'm afraid the scenario you are attempting is not really supported.
The key storage only stores the private key - the certificate to which it belongs is supposed to be stored in certificate storage. Calling LoadPfx
with PersistKeySet
results in a persisted private key, but non-persisted certificate, which is somewhat contradictory.
The Certificate
class features Associate(..., bool permanentBind)
method that could be used to associate a private key with a certificate, but the relevant overload is not available for .NET Compact Framework.
However, what are you actually trying to achieve? If you only need to "store a private key in the key storage" and "retrieve it when needed", consider using RSACryptoServiceProvider
to achieve that together with your PFXUtil.GetPrivateKeyFromPFXFile
method. The following helper methods might be useful:
public static void SavePrivateKey(RSAParameters privateKey, string keyContainerName)
{
var parameters = GetCspParameters(keyContainerName);
parameters.Flags = CspProviderFlags.NoFlags;
var rsa = new RSACryptoServiceProvider(parameters);
rsa.PersistKeyInCsp = true;
rsa.ImportParameters(privateKey);
rsa.Clear();
}
public static RSAParameters GetPrivateKey(string keyContainerName)
{
var parameters = GetCspParameters(keyContainerName);
parameters.Flags = CspProviderFlags.UseExistingKey;
var rsa = new RSACryptoServiceProvider(parameters);
var privateKey = rsa.ExportParameters(true);
rsa.Clear();
return privateKey;
}
private static CspParameters GetCspParameters(string keyContainerName)
{
var rsa = new RSACryptoServiceProvider();
string providerName = rsa.CspKeyContainerInfo.ProviderName;
int providerType = rsa.CspKeyContainerInfo.ProviderType;
rsa.Clear();
var parameters = new CspParameters(providerType, providerName, keyContainerName);
parameters.KeyNumber = (int)KeyNumber.Exchange;
return parameters;
}