c# System.Security.Cryptography 提示系统找不到指定的文件

作者:zarte    发布时间: 2020-11-22

netc#rsa

问题

站点登录信息前端采用rsa加密后传到后端解密。
后端代码:

//定义私钥
string privateKey = @"..==";
    try
    {
        RSACryptoServiceProvider rsaCryptoServiceProvider = CreateRsaProviderFromPrivateKey(privateKey);
        //把+号,再替换回来
        userName = userName.Replace("%2B", "+");
        userName = userName.Replace(" ", "+");
        userPass = userPass.Replace("%2B", "+");
        userPass = userPass.Replace(" ", "+");
        byte[] res = rsaCryptoServiceProvider.Decrypt(Convert.FromBase64String(userName), false);
        byte[] res2 = rsaCryptoServiceProvider.Decrypt(Convert.FromBase64String(userPass), false);
        userName = Encoding.UTF8.GetString(res);
        userPass = Encoding.UTF8.GetString(res2);
    }
    catch (Exception exception)
    {
        return "{'code':4,'msg':'rsa解码错误" + exception.Message + "'}";
     }

异常信息:系统找不到指定的文件

解决

打开IIS设置,应用程序池--》找到自己的应用程序(网站名称)-->右键-->高级设置-->在进程模型区域,有个-用户加载配置文件-选择后面为true.这个问题就解决了。 Img

原因

.NET的RSA加密会加载密钥到密钥存储区,用户加载配置文件为false时,没有密钥存储区的访问权限。所以报“系统找不到指定的文件。”

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.

  1. Which options do we have here then?
  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:

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

上一篇:  创建ca证书并签发ip证书与泛域名证书

下一篇:  phpunit超详细使用教程

加载更多