加密异常未处理:系统找不到指定的文件。

110

我正在尝试掌握SSL通信的奥秘,并在这个网站上找到了一个很棒的教程。我想测试自己的证书。使用Visual Studio 2012,我只需添加现有文件(我的证书为.pfx格式),然后更改app.config中的“certificate”和“password”设置。但是,当我尝试运行它时,出现了错误:

CryptographicException was unhandled: System cannot find the specified file

接着,在我的Web服务中,我也尝试了同样的操作。那里我得到了更多关于错误的详细信息:

System.Security.Cryptography.CryptographicException: System cannot find specified file.

   at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
   at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertFileType(String fileName)
   at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
   v System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
   v TestServer.DataService.LoadSoap() v c:\Users\Administrator\Documents\Visual Studio 2012\Projects\TestServer\TestServer\DataService.asmx.cs:line 48

我写了一封信给文章的作者,但由于他最后一次回复是在2012年3月,所以我不确定他是否会回复。如果有人能帮助我解决这个问题,我将非常感激。

附言:在从 .cer 导出证书到 .pfx 时,我更改了导出文件的标题。虽然我怀疑它对问题的影响,但我还是想提一下。


2
你是否指定了文件的完整路径名? - gtrig
1
哇...现在我感觉自己像个彻头彻尾的白痴。在指定完整路径后,它起作用了...好吧,客户说证书无效,但这可能是因为它是为我的旧电脑发行的。所以,谢谢你...我认为,这个话题可以关闭为非建设性的。 - Storm
1
针对Azure应用服务中的相同问题 - 在Azure上使用Certenroll生成自签名证书 - RBT
7个回答

325

您是否在IIS的应用程序池中进行了以下设置?

  1. 进入IIS管理器
  2. 进入应用程序池实例
  3. 点击高级设置
  4. 在进程模型下,将“加载用户配置文件”设置为true

有关更多信息,请参见此stackoverflow问题:当我设置IIS池的LoadUserProfile时会发生什么?


1
https://dev59.com/vWQn5IYBdhLWcg3wCjb0 - nologo
谢谢您!我已经为这个错误苦苦挣扎了几个月。每次都不得不重新启动服务器或重启IIS,以便在错误再次出现之前“有时间”。 - Miquel Coll
4
天啊,这是多么荒谬的错误!!我一直在检查文件名,但却找不到任何问题。***加密异常提示文件路径错误,实际上并非如此。 - Hoàng Long
4
在Azure中:使用“应用程序设置” -> 添加“WEBSITE_LOAD_USER_PROFILE”,并将其值设置为“1”。 - hanzolo
1
只是想补充一下,(1)我的应用程序是一个.NET 6 + Angular 应用程序,(2)“指定文件的完整路径名称”没有任何益处(位置/名称在appsettings.json中指定),(3)我正在使用托管站点,这个特定的IIS设置无法在提供的控制面板中查看或设置。支持人员必须进行IIS设置更新,结果是:pfx证书被正确处理。 - StackOverflowUser
显示剩余3条评论

30

对于那些在尝试使用 Import 方法导入 X509Certificate2 时收到 Cryptographic Exception 的人,我发现使用 MachineKeySet 的 Enum 选项可以绕过需要在 IIS 中创建 userContext 的步骤,从而更容易实现。

X509Certificate2 cert = new X509Certificate2();
cert.Import(certificateFilePath, certPasshrase, 
X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

2
只需这样做,你就会很开心。在Windows 10 2004中使用IIS无法正常工作。我尝试了每种可能的组合,但这个方法非常有效。 - Daniel Dolz

13

通过传递带有csdMachineKeyKeyStore标志的CspParameters,IIS可以绕过抛出异常的限制。

CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = Guid.NewGuid().ToString().ToUpperInvariant();
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams);

我在这里找到了解决方案。


1
我没有足够的话语来描述我对您这个简单修复的感激之情!谢谢!!在我的情况下,本地一切都正常,但在Azure上我收到了“..找不到指定的文件”错误。这个修复解决了它。 - Reath

6

您需要指定绝对路径而不是相对路径。

AppDomain.CurrentDomain.BaseDirectory +"/Certificate/cer.PFX"

6

因为这个问题的搜索排名很高,我想提供一种在ASP.net应用程序中使用绝对路径(它只接受绝对路径)来指定相对位置的pxf密钥文件的方法。

    string path = HttpContext.Current.Server.MapPath("~") + "..\keys\relative_key.pfx";

    X509Certificate2 cert = new X509Certificate2(path, "", X509KeyStorageFlags.DefaultKeySet);

1
太棒了!原来我遇到这个错误的原因是我的证书路径略有偏差。 - Suamere

5

对于那些试图从Windows证书存储(本地计算机的证书)访问证书的人,请确保使用“操作” ->“所有任务” ->“管理私钥...”给应用程序池用户访问证书的私钥。不这样做会导致我遇到这个错误。


这正是我所需要的,谢谢 - 我使用了这个指南将我的应用程序池添加到权限集中,因为应用程序池并不以用户身份运行 - https://community.progress.com/s/article/How-to-set-folder-permissions-for-a-site-that-uses-ApplicationPoolIdentity - Poat

0

补充schmiddy98上面的答案,我允许IIS用户访问这个文件夹:

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接