为什么我会在X509CertificateStore上的OpenRead中获得ExecutionEngineException?

时间:2009-03-24 13:10:12

标签: c# certificate

我正在使用带有安全性令牌的WebServicesClientProtocol类,并使用以下代码查找要使用的安全性令牌:

private static X509SecurityToken GetSecurityCertificate(string subject)
{
    X509CertificateStore localStore = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
    X509SecurityToken securityToken = null;
    if (localStore.OpenRead())
    {
       X509CertificateCollection certificateCollection = localStore.FindCertificateBySubjectString(subject);
        if (certificateCollection.Count == 0) throw new Exception("Skilríki finnst ekki í skilríkjageymslu");
        securityToken = new X509SecurityToken((X509Certificate)certificateCollection[0]);
    }
    localStore.Close();
    return securityToken;
}

时不时(但并非总是如此,我一直无法弄明白)究竟是什么时候我得到以下异常:

alt text http://www1.ruedenet.is/files/exception.png

1 个答案:

答案 0 :(得分:1)

我今天遇到了这个问题,我相信我已经弄明白是什么导致了这个问题。静态方法需要同步。

如果您在异常时将鼠标悬停在localStore变量上并检查Certificates属性,您很可能会看到“InvalidOperationException”的影响 - 要访问证书,您必须使用Open()或OpenRead()。 ......等等等等。“

正在发生的事情是某个线程在另一个线程完成访问之前关闭了商店。

我首先创建了一个用于锁定商店的静态类成员来解决这个问题:

private static object m_storeLock = new object();

当您访问商店时,您必须执行以下操作:

public static X509Certificate FindCertificate(string certName) {
    X509CertificateStore store = null;            
    X509Certificate cert = null;

    lock (m_storeLock) {
        try {                    
            store = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
            store.OpenRead();

            X509CertificateCollection col =
            (X509CertificateCollection)store.FindCertificateBySubjectString(certName);

            if (col.Count > 0) {      
                cert = col[0];
            }
        }
        catch {
        }
        finally {
            if (store != null) {
                store.Close();
            }
        }
    }                           

    if (cert == null) {
        throw new ArgumentException("Certificate not found!");
    }

    return cert;
}

为了更安全,你应该锁定局部变量“cert”,但这不是生产代码人......:D~