10

我们有一些单元测试,其中嵌入了 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, Boolean 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

4 回答 4

26

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

于 2018-07-19T20:36:25.370 回答
6

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

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

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

于 2013-05-23T20:02:04.017 回答
0

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

X509Certificate2 x509Certificate = new X509Certificate2("YourKey.pfx", "yourPassword", X509KeyStorageFlags.MachineKeySet);

于 2020-11-27T10:17:17.190 回答
0

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

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

于 2020-11-19T12:24:59.113 回答