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

当在ASP.NET中使用RSACryptoServiceProvider时,可能会遇到'系统找不到指定的文件'的CryptographicException。问题出在CryptAcquireContext API上,错误#2表示用户配置文件未加载。解决方案包括:1) 使用LoadUserProfile加载用户配置文件,但需要高权限;2) 创建一个使用用户凭证的空Windows服务,由服务控制管理器自动加载用户配置文件;3) 使用机器密钥存储,通过传递CRYPT_MACHINE_KEYSET标志给CryptAcquireContext。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

改为

  

 

相关阅读:

will talk today about a very common issue we face when we try to use .NET's RSACryptoServiceProvider class in ASP.NET.

When we try to create a new RSACryptoServiceProvider object in this scenario, we may get the following exception:

"System.Security.Cryptography.CryptographicException: The system cannot find the file specified".

 

By using my CryptoAPI Tracer script we can take a look to the CryptoAPI calls that .NET is making behind the scenes. Thanks to this script we will be able to see the exact API that is failing and the exact error (which most of the time .NET masks).

In our case, the API that fails is CryptAcquireContext, and it fails with error #2 (ERROR_FILE_NOT_FOUND). According to CryptAcquireContext documentation, this error means the following:
"
The profile of the user is not loaded and cannot be found. This happens when the application impersonates a user, for example, the IUSR_ComputerName account.
"

By default, ASP.NET won't load the user profile. Take a look to the parameters of the problematic CryptAcquireContext call as being shown in the log file that my script generated. If this API is not being called with CRYPT_MACHINE_KEYSET (to use the machine profile) or CRYPT_VERIFYCONTEXT (to use temporary key stores), it will try to access the key stores in the user profile, and it will fail because its not loaded.

Which options do we have here then?

1) If we need each user running your ASP.NET app to use their own key stores, we will have to load their user profile. We can do it with LoadUserProfile API. The only problem is that the privileges needed to execute this API are quite powerful for a standard user.

2) If we still need the user profile and don't want to give users enough privileges to run LoadUserProfile, there is a trick we can use: Service Control Manager (SCM) will automatically load the profile of the user that a Windows service uses to run. So we may create a dummy Windows service which runs with our user's credentials. This service won't need to do anything special, just stay alive. SCM will load the user profile for us and ASP.NET will be able to use it automatically once it gets loaded.

3) We may also use machine key stores instead of user's. We just have to pass CRYPT_MACHINE_KEYSET flag to CryptAcquireContext. In order to do that in .NET, we may use a code like this: 

CspParameters RSAParams = new CspParameters();
RSAParams.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider sp = new RSACryptoServiceProvider(1024, RSAParams);

Note. When we use machine key stores, any user in that machine may have access to those keys.

 

http://blogs.msdn.com/b/alejacma/archive/2007/12/03/rsacryptoserviceprovider-fails-when-used-with-asp-net.aspx

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值