【问题标题】:RSACryptoServiceProvider CryptographicException System Cannot Find the File Specified under ASP.NETRSACryptoServiceProvider CryptographicException 系统找不到 ASP.NET 下指定的文件
【发布时间】:2010-11-09 07:51:56
【问题描述】:

我有一个使用 RSACryptoServiceProvider 使用已知私钥(存储在变量中)解密某些数据的应用程序。

当 IIS 应用程序池配置为使用网络服务时,一切运行正常。

但是,当我们配置 IIS 应用程序池以在不同的身份下运行代码时,我们会得到以下信息:

System.Security.Cryptography.CryptographicException:系统找不到指定的文件。

   在 System.Security.Cryptography.Utils.CreateProvHandle(CspParameters 参数,布尔随机密钥容器)
   在 System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters 参数)
   在 System.Security.Cryptography.RSA.FromXmlString(字符串 xmlString)

代码是这样的:

byte[] input; 
byte[] output; 
string private_key_xml; 

var provider = new System.Cryptography.RSACryptoServiceProvider(this.m_key.Key_Size);
provider.FromXmlString(private_key_xml); // Fails Here when Application Pool Identity != Network Service

ouput = provider.Decrypt(input, false); // False = Use PKCS#1 v1.5 Padding

有些资源试图通过说明您应该授予用户对机器密钥存储的读取权限来回答这个问题 - 但是没有解决此问题的明确答案。

环境:IIS 6.0、Windows Server 2003 R2、.NET 3.5 SP1

【问题讨论】:

    标签: .net asp.net cryptography application-pool


    【解决方案1】:

    我通过在应用程序池的高级设置/进程模型部分将“加载用户配置文件”设置为 True(为 False)来解决此问题。

    该应用程序在 Server 2003 R2 / IIS 6 上运行良好,当我在我们的新 2008 R2 服务器上配置它时出现了问题。

    有想法尝试一下:

    http://social.msdn.microsoft.com/forums/en-US/clr/thread/7ea48fd0-8d6b-43ed-b272-1a0249ae490f/

    YMMV

    【讨论】:

    • 这是因为密钥存储在 DPAPI security.stackexchange.com/q/1771/396
    • 谢谢,在服务器上为我工作,但不是在本地,我想知道为什么。我读到这个函数尝试访问密钥库并由于权限而失败,即使代码不需要密钥库。
    • 好的,我发现它为什么不能在我的机器上工作了。这是因为我使用了一个应用程序池,它已经用于其他应用程序了。我不太清楚它为什么会导致问题,但是当我设置一个专用的应用程序池时,它起作用了!
    • 谢谢!仅在生产中遇到此问题,这解决了它。
    • 有谁知道它为什么有效?它在 2008 年工作,但在 2012 年停止。@Tim 说它应该在 2008 年停止工作。
    【解决方案2】:

    确实需要编写这样的代码

    CspParameters _cpsParameter;
    RSACryptoServiceProvider RSAProvider;
    
    _cpsParameter = new CspParameters();
    _cpsParameter.Flags = CspProviderFlags.UseMachineKeyStore;
    
    RSAProvider = new RSACryptoServiceProvider(1024, _cpsParameter); 
    

    以下用户需要访问该文件夹:C:\Documents and Settings\All Users\Application data\Microsoft\Crypto\RSA\MachineKeys

    1. IIS 用户帐户(匿名)
    2. 您在 web.config 设置中用于模拟您的应用程序的用户帐户。

    所以现在它对我来说很好。

    【讨论】:

    • 感谢您的回答 - 我还没有机会实际测试这个。您是否知道默认情况下新帐户(干净的 Windows 安装)是否已经可以访问此帐户?我们试图避免进行过多的修改 - 对于应该在低/中等信任下运行的东西来说,这似乎是一个特别奇怪的问题。
    • 威尔,我不确定!这个特殊问题只发生在我的机器上。我已经尝试过另一台开发人员机器并且事情按预期工作。在服务器中,我们的系统在不同的用户环境下运行,所以我也没有问题。
    【解决方案3】:

    尝试设置

    System.Security.Cryptography.RSACryptoServiceProvider.UseMachineKeyStore = true;
    

    编辑: 然后尝试使用

    var provider = new System.Security.Cryptography.RSACryptoServiceProvider();
    

    而不是带有整数参数的构造函数。该构造函数尝试生成具有指定密钥长度的密钥,而您可能无法使用您的权限执行此操作。

    【讨论】:

    • 这适用于我在 IIS7 上使用默认的 apppool 身份。
    • 如果您不想全局启用该标志,您似乎也可以调用“new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore })”。
    • 这也修复了我在实例化 RSACryptoServiceProvider 时访问被拒绝的错误。
    【解决方案4】:

    我只是想评论一下 Rasmus Faber 的解决方案对我有用(稍作修改):

    System.Cryptography.RSACryptoServiceProvider.UseMachineKeyStore = true;
    RSACryptoServiceProvider provider = new System.Cryptography.RSACryptoServiceProvider();
    

    我试图让 MailBee.net 使用 DKIM 签署外发消息,并得到了 OP 收到的相同消息。当然,在我的开发机器上一切都很好,但是在上传到我的客户虚拟主机时,我遇到了这个问题。就像我说的,上面的解决方案对我有用,而我在网上找到的其他解决方案(包括上面的 msdn 论坛链接)没有。

    (我会投票和评论,但我没有足够的代表这样做。:P)

    感谢拉斯穆斯费伯!

    【讨论】:

      【解决方案5】:

      只有当我添加时

      标志 = CspProviderFlags.UseMachineKeyStore

      问题为我解决了。

      {
          string keyName = "Secret***";
          CspParameters parameters = new CspParameters()
          {
              KeyContainerName = keyName,
              Flags = CspProviderFlags.UseMachineKeyStore
          };
      }
      

      【讨论】:

        猜你喜欢
        • 2013-07-24
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 2016-02-08
        • 2013-11-21
        • 2023-03-17
        • 2017-12-21
        相关资源
        最近更新 更多