【问题标题】:SslStream Authentication fails under LOCAL SYSTEM account本地系统帐户下的 SslStream 身份验证失败
【发布时间】:2017-07-10 15:25:11
【问题描述】:

我有这个代码:

string certificateFilePath = @"C:\Users\Administrator\Documents\Certificate.pfx";

string certificateFilePassword = "Some Password Here";

X509Certificate clientCertificate = new X509Certificate(certificateFilePath, certificateFilePassword);

TcpClient client = new TcpClient(host, port);

SslStream stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true);

X509CertificateCollection clientCertificates = new X509CertificateCollection {clientCertificate};

stream.AuthenticateAsClient(host, clientCertificates, SslProtocols.Tls, false);

当我在控制台应用程序中运行代码时,一切正常,stream.IsAuthenticatedstream.IsMutuallyAuthenticated 返回 truestream.LocalCertificate 包含正确的证书对象。

但是,当在 Windows Service (as LOCAL SYSTEM user) 中运行完全相同的代码时,虽然 stream.IsAuthenticated 返回 truestream.IsMutuallyAuthenticated 返回 falsestream.LocalCertificate 返回 null

在这两种情况下都会发生这种情况,在运行第一行 clientCertificate 后会加载正确的认证数据并包含证书的 SubjectIssuer 的正确信息。

我还尝试使用此代码强制 SslStream 选择证书:

string certificateFilePath = @"C:\Users\Administrator\Documents\Certificate.pfx";

string certificateFilePassword = "Some Password Here";

X509Certificate clientCertificate = new X509Certificate(certificateFilePath, certificateFilePassword);

TcpClient client = new TcpClient(host, port);

SslStream stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true, (sender, host, certificates, certificate, issuers) => clientCertificate);

X509CertificateCollection clientCertificates = new X509CertificateCollection {clientCertificate};

stream.AuthenticateAsClient(host, clientCertificates, SslProtocols.Tls, false);

但是代码仍然不起作用,stream.IsMutuallyAuthenticated 返回falsestream.LocalCertificate 返回null

我已经探索了几天,但我无法弄清楚。非常感谢任何帮助。

编辑: 使用 WinHttpCertCfg 工具尝试证书后,发现与similar question(s) 不同,LOCAL SYSTEM 帐户已经可以访问目标证书的私钥,如下图所示: 因此问题仍然没有解决。

【问题讨论】:

  • 如果您尝试以NETWORK SERVICELOCAL SERVICE 而不是LOCAL SYSTEM 运行服务会发生什么?
  • @CamiloTerevinto 我会试试看,几分钟后回复你。
  • NETWORK SERVICELOCAL SERVICELOCAL SYSTEM @CamiloTerevinto 的结果完全相同
  • 你能以管理员身份运行它并告诉我们吗?
  • 它以管理员@Juan 的身份完美运行

标签: c# authentication ssl sslstream local-system-account


【解决方案1】:

我终于在玩 X509 类的同时让代码工作了。

这是对我有用的代码:

string host = "The Host";

int port = 777;

string certificateFilePath = @"C:\Users\Administrator\Documents\Certificate.pfx";

string certificateFilePassword = "Some Password Here";

X509Certificate clientCertificate = new X509Certificate(certificateFilePath, certificateFilePassword);

X509Certificate2 clientCertificate2 = new X509Certificate2(clientCertificate); //<== Create a X509Certificate2 object from the X509Certificate which was loaded from the file. The clientCertificate2 loads the proper data

TcpClient client = new TcpClient(host, port);

SslStream stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true);

X509CertificateCollection clientCertificates = new X509CertificateCollection { clientCertificate2 }; //<== Using the clientCertificate2 which has loaded the proper data instead of the clientCertificate object

stream.AuthenticateAsClient(host, clientCertificates, SslProtocols.Tls, false);

这样我的代码可以从系统中找到正确的 X509Store、证书和私钥。

我已经通过经验解决了这个问题。不过,我在 MSDN 上找不到关于为什么它应该是这样的明确解释。

【讨论】:

    【解决方案2】:

    我们用于此类服务问题的一种调试技术是使用像PsExec 这样的实用程序。这将允许您作为必要的服务帐户运行交互式进程。

    -s 在系统账户中运行进程。

    帮助内容会说“远程进程”,但也可以用于本地进程。

    例如, 在具有管理员权限的命令提示符中运行以下命令后,以下命令将为您提供系统帐户的命令提示符

    PsExec.exe -s cmd
    

    在命令窗口中,可以使用WhoAmI命令查看

    C:\Windows\system32>whoami
    nt authority\system
    

    这将使您能够进行一些交互式测试来尝试不同的组合。

    SYSTEM 帐户在本地计算机中有maximum possible privilege

    您还会看到创建自定义帐户来运行服务是推荐的选项。但是,这有维护另一个密码的开销。在较新版本的 Windows 中,有一个 managed service accounts。这可能是一个更好的选择。

    托管服务帐户和虚拟帐户 — 旨在为应用程序提供自己帐户的隔离,同时无需管理员手动管理这些帐户的 SPN 和凭据。

    【讨论】:

    • 如果您阅读了关于我的问题的 cmets,我已经尝试在 NETWORK SERVICELOCAL SERVICELOCAL SYSTEM 中运行该进程以查看是否存在任何权限问题等,我一直在使用 PsExec.exe-s 标志或其他命令来这样做,但它没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2017-07-25
    相关资源
    最近更新 更多