创建X509Certificate2对象时,为什么会出现“拒绝访问”错误?

时间:2013-03-08 01:14:08

标签: .net x509certificate x509certificate2

我们有一些单元测试,其中嵌入了PFX证书。在测试执行期间读取这些证书并将其转换为X509Certificate2个对象。不幸的是,当以非特权用户身份运行时,我们得到Access Denied例外:

using (var s = EmbeddedResourceUtilities.GetEmbeddedResourceAsStream(typeThatContainsEmbeddedResource, certFileName))
{
    if (s == null)
    {

        throw new ApplicationException(String.Format("Embedded certificate {0} for type {1} not found.", certFileName, typeThatContainsEmbeddedResource.FullName));
    }

    try
    {
        var bytes = new byte[s.Length];
        s.Read(bytes, 0, (int)s.Length);
        return new X509Certificate2(bytes);
    }
    catch (Exception ex)
    {
        throw new ApplicationException(String.Format("Error loading embedded certificate {0} for type {1}.", certFileName, typeThatContainsEmbeddedResource.FullName), ex);
    }
}

以下是例外:

  

System.Security.Cryptography.CryptographicException:拒绝访问。
     在System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
    在System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte [] rawData,IntPtr密码,UInt32 dwFlags,布尔persistKeySet,SafeCertContextHandle& pCertCtx)
    在System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte [] rawData,Object password,X509KeyStorageFlags keyStorageFlags)
    在System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte [] rawData)

我已经尝试修改构造函数以使用空密码和显式键集标志,但这并不能解决它:

// this doesn't work, either
return new X509Certificate2(bytes, String.Empty, X509KeyStorageFlags.MachineKeySet);

我在其他地方读过,我应该给我的非特权用户增加MachineKeys目录的权限,但我不喜欢这样做,因为它允许生产代码假设这些权限在测试环境之外的该目录上可用。

有没有办法让非特权用户从文件加载X509Certificate?

4 个答案:

答案 0 :(得分:6)

在X509Certificate2构造函数中使用“ X509KeyStorageFlags.UserKeySet”标志可以帮助我。

答案 1 :(得分:5)

这是我对正在发生的事情的最好猜测。

X509Certificate2构造函数在Machine Keys目录中创建临时公钥/私钥对象(我相信通过Windows本地安全机构)。由于我们的非特权用户无权访问这些密钥或Machine Keys目录,因此测试失败。

我们的解决方案是更新我们的环境设置脚本以提前安装这些测试证书,授予非特权用户权限,并重新编写测试以从相应的证书存储区加载证书。

答案 2 :(得分:0)

我的原因是另外两个。 我认为在最新的Windows版本2019和Windows 10上,可以将pfx编码的证书加密为TripleDES-SHA1和AES256-SHA256。 在较旧的Windows版本上,即使密码正确,此操作也会失败,并显示“拒绝访问”。

另一个原因是证书存储中可能不存在中间权限和根权限。确保首先通过从.p7b导入到本地计算机来导入它们。现在,该证书将被标记为可用于SSL服务(例如),并且“访问被拒绝”不再有效。

答案 3 :(得分:0)

我的解决方案是指定X509KeyStorageFlags.MachineKeySet标志

X509Certificate2 x509Certificate =新的X509Certificate2(“ YourKey.pfx”,“ yourPassword”,X509KeyStorageFlags.MachineKeySet);

相关问题