2015-02-11 52 views
2

以下方法用于使用“SHA1”对照公钥验证数据。该方法第一次被调用是正确的。然而,当该方法被称为第二次及以后的下面一行.NET RSACryptoServiceProvider为什么会抛出“安全句柄已关闭”异常?

isVerified = RSA.VerifyData(tokenData, CryptoConfig.MapNameToOID(hashType), signature); 

导致该异常是什么,我可能会错误地做

{"Safe handle has been closed"} System.Exception {System.ObjectDisposedException} 

的思考?

internal static bool VerifyTokenData(byte[] tokenData, byte[] signature, string hashType) 
{ 
    try 
    { 
    bool isVerified = false; 

    using (RSACryptoServiceProvider RSA = (RSACryptoServiceProvider)CompanyAuthentication.publicKey) 
    { 
     isVerified = RSA.VerifyData(tokenData, CryptoConfig.MapNameToOID(hashType), signature); 
    } 

    return isVerified; 
    } 
    catch (CryptographicException cryptoExc) 
    { 
    throw new InvalidOperationException("Exception verifying token data", cryptoExc); 
    } 
    catch (Exception exc) 
    { 
    throw new InvalidOperationException("Exception verifying token data", exc); 
    } 
} 

使用的公开密钥加载到使用

internal static void LoadKeys() 
{ 
    try 
    { 
    X509Certificate2 certificate = new X509Certificate2(); 
    lock (CompanyAuthentication.thisLock) 
    { 
     certificate.Import(System.Configuration.ConfigurationManager.AppSettings["companyKeyFilePath"].ToString(), System.Configuration.ConfigurationManager.AppSettings["companyKeyFilePassword"].ToString(), X509KeyStorageFlags.UserKeySet); 
     CompanyAuthentication.publicKey = certificate.PublicKey.Key; 
     CompanyAuthentication.privateKey = certificate.PrivateKey; 
    } 
    } 
    catch (CryptographicException cryptoExc) 
    { 
    throw new InvalidOperationException("Exception creating public/private keys", cryptoExc); 
    } 
    catch (Exception exc) 
    { 
    throw new InvalidOperationException("Exception creating public/private keys", exc); 
    } 
} 

编辑类变量: 下面是修改后的代码正确,其功能。它每次加载密钥文件,而不是在类构造器中加载一次。

SalesNetAuthentication.LoadKeys(); 
    using (RSACryptoServiceProvider RSA = (RSACryptoServiceProvider)SalesNetAuthentication.publicKey) 
    { 
     isVerified = RSA.VerifyData(tokenData, CryptoConfig.MapNameToOID(hashType), signature); 
    } 
+0

它就像你驾驶一辆汽车,并把它停在电线杆上以结束你的旅程。如果你买了这辆车,那么没有人会在意这件事。如果你从你的朋友借来的话,他会说点什么。 – 2015-02-11 23:34:19

+0

下面的两个答案都指出与使用{}块内调用的.Dispose()方法有关的问题。此MSDN文档(https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider%28v=vs.90%29.aspx)在重要说明中指出,使用{}块应该用于w/RSACryptoServiceProvider。因此,我试验并发现,如果每次调用RSACryptoServiceProvider时都加载密钥文件,则使用{}语句会正常工作(请参阅编辑问题)。 – ChrisP 2015-02-12 00:06:51

回答

2

既然你有using (RSACryptoServiceProvider RSA = ...它的配置对象的时候using范围结束。

解决方案将删除using,以便该对象可用于后续尝试,或每次需要使用时重新创建该对象。

1

问题是,您正在重新使用CompanyAuthentication.publicKey,即使您第一次调用它(将其封装在使用块中导致调用.Dispose()方法时)已经处理了它。

我不认为你想要处置这个对象,如果你打算继续使用它。由于这看起来是一个静态变量,因此您可能不希望在关闭应用程序之前处理它。

相关问题