Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
698 views
in Technique[技术] by (71.8m points)

ssl - What is the impact of the `PersistKeySet`-StorageFlag when importing a Certificate in C#

In my application, a Certificate for Client-Authentication is programatically added to the MY-Store using the following code:

//certData is a byte[]
//password is a SecureString
X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable);
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
    store.Open(OpenFlags.ReadWrite);
    store.Add(certificate);
}
finally
{
    store.Close();
}

With this code, the certificate was correctly imported into the MY-Store (thumbprint and certification chain also correct) on all machines I tested.

But on some machines (Windows 7 Professional SP1 and Widnows Server 2008 R2 with local user account) the Certificate could afterwards not be used for client-authentication ("Could not establish trust relationship for the SSL/TLS secure channel"). On a Windows 8.1 Enterprise machine with domain user account, authentication worked sometimes but not always.

I desperatly tried a couple of things, and finally found a solution in adding X509KeyStorageFlags.PersistKeySet to the storage flags. So the first line is now:

X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

With these flags, the certificate could be used on all devices. Even though I am happy that my application now works in the expected way, I would like to understand why? What exactly does the PersistKeySet-Flag do and why does it have an impact on when and by whom the certificate can be used?

MSDN was not very helpful in this case.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When importing a PFX the public certificate element is loaded into memory, and the private key material is squirreled away into a key storage provider. The default behavior in .NET is to delete the private key material when the X509Certificate2 object is Disposed (or its resources are being Finalized via Garbage Collection). The PersistKeySet flag prevents this cleanup from happening.

If you're adding to a persisted certificate store, you always want to set PersistKeySet. When not adding to a persisted store you very likely do not want it set.

If your importing process is long-lived then the behavior you'd see is that at an arbitrary time after the import new accesses to the private key start failing. If it's short-lived then it probably always failed to work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...