C#中的OPC UA安全连接

3
我对OPC UA协议还很陌生,最近使用OPCFoundation库编写了一个C接口来连接机器。到目前为止,我没有处理证书,因为所有机器都允许未经保护的连接。
现在需要连接使用证书的机器,我应该如何修改代码以模拟UAExpert软件上“信任服务器证书”的操作呢?这个软件会警告关于证书,但允许我信任机器的证书(将其保存到本地文件夹)并继续会话。
在我的代码中,我设置了“AutoAcceptUntrustedCertificates = true”,但当我尝试打开会话时,出现了以下错误:
Opc.Ua.ServiceResultException "证书不受信任。\r\n主题名称:CN=NxOpcUaServer@192.168.1.10 ..."
谢谢您提前的帮助。
    using Opc.Ua;
    using Opc.Ua.Client;
    using Opc.Ua.Configuration;

    private static String CallOpcUA(string indirizzoMacchina, string displayNome, string idNodo)
    {
        var config = new ApplicationConfiguration()
        {
            ApplicationName = "MyApp",
            ApplicationUri = Utils.Format(@"urn:{0}:MyApp", System.Net.Dns.GetHostName()),
            ApplicationType = ApplicationType.Client,
            SecurityConfiguration = new SecurityConfiguration
            {
                ApplicationCertificate = new CertificateIdentifier { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", SubjectName = "MyApp" },
                TrustedIssuerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Certificate Authorities" },
                TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Applications" },
                RejectedCertificateStore = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\RejectedCertificates" },
                AutoAcceptUntrustedCertificates = true
            },
            TransportConfigurations = new TransportConfigurationCollection(),
            TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
            ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
            TraceConfiguration = new TraceConfiguration()
        };
        config.Validate(ApplicationType.Client).GetAwaiter().GetResult();
        if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
        {
            config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
            config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateTimeInvalid); };
        }

        var application = new ApplicationInstance
        {
            ApplicationName = "MyApplication",
            ApplicationType = ApplicationType.Client,
            ApplicationConfiguration = config
        };

        try
        {
            application.CheckApplicationInstanceCertificate(false, 2048).GetAwaiter().GetResult();
        }
        catch (System.IO.FileLoadException e)
        {
        }

        try
        {
            identity = new UserIdentity();

            var selectedEndpoint = CoreClientUtils.SelectEndpoint(indirizzoMacchina, useSecurity: false);

            using (var session = Session.Create(config, new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)), false, "", 60000, identity, null).GetAwaiter().GetResult())
            {
               
                [read value from the node]

            }

        }
        catch (Opc.Ua.ServiceResultException e)
        {
        }
        
    }
3个回答

0
这可能对问题的作者来说已经太晚了,但它可能会帮助其他人。
尝试添加一个证书验证器,自动接受不受信任的证书:
    var config = new ApplicationConfiguration()
    {
        ApplicationName = "MyApp",
        ApplicationUri = Utils.Format(@"urn:{0}:MyApp", System.Net.Dns.GetHostName()),
        ApplicationType = ApplicationType.Client,
        SecurityConfiguration = new SecurityConfiguration
        {
            ApplicationCertificate = new CertificateIdentifier { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", SubjectName = "MyApp" },
            TrustedIssuerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Certificate Authorities" },
            TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Applications" },
            RejectedCertificateStore = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\RejectedCertificates" },
            AutoAcceptUntrustedCertificates = true
        },
        TransportConfigurations = new TransportConfigurationCollection(),
        TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
        ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
        TraceConfiguration = new TraceConfiguration(),

        // ***** ADD THIS ***** //
        CertificateValidator = new CertificateValidator() { AutoAcceptUntrustedCertificates = true },
    };

0

只是一个快速修复,请将此替换:

if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
{
    config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
    config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateTimeInvalid); };
}

对于这个:

if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
{
    config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = true; };
}

我在几个不同的服务器上都试过,都成功了。


0

使用OPC UA安全端点时,您必须始终提供客户端证书。您不能省略此步骤,服务器应该将此证书列入其信任列表中。否则,服务器可能会拒绝您的连接。

我在您的代码中看不到您提供客户端证书的部分。

您无法通过客户端自动接受不受信任证书的方式来覆盖此设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接