编程语言
首页 > 编程语言> > c# – SslStream身份验证在LOCAL SYSTEM帐户下失败

c# – SslStream身份验证在LOCAL SYSTEM帐户下失败

作者:互联网

我有这个代码:

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.IsAuthenticated和stream.IsMutuallyAuthenticated返回true,stream.LocalCertificate包含正确的证书对象.

但是,当在Windows服务(作为LOCAL SYSTEM用户)中运行完全相同的代码时,虽然stream.IsAuthenticated返回true,但stream.IsMutuallyAuthenticated返回false,stream.LocalCertificate返回null.

在两种情况下都会发生这种情况,在第一行运行之后,clientCertificate会加载正确的证书数据并包含证书的主题和颁发者的正确信息.

我还尝试使用此代码强制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返回false并且stream.LocalCertificate返回null.

我已经探索了几天了,我无法弄明白.任何帮助都非常感谢.

编辑:
使用WinHttpCertCfg工具尝试证书后,事实证明,与similar question(s)不同,LOCAL SYSTEM帐户已经可以访问目标证书的私钥,如下图所示:
Output from WinHttpCertCfg tool for the target certificate
因此问题仍然没有解决.

解决方法:

我终于在使用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上.

标签:c,authentication,ssl,sslstream,local-system-account
来源: https://codeday.me/bug/20190627/1306806.html