OPC UA C# 中的安全连接

问题描述 投票:0回答:4

我对 OPC UA 协议还很陌生;我最近编写了一个 C 接口来使用 OPCFoundation 的库连接到一些机器,到目前为止我不必处理证书,因为所有机器都允许不安全的连接。

现在连接到使用证书的计算机,我应该如何修改我的代码以模拟我可以在 UAEExpert 软件上执行的“信任服务器证书”操作,该操作会警告证书,但允许我信任来自的证书机器(将其保存到本地文件夹)并继续会话?

在我的代码中,我有

"AutoAcceptUntrustedCertificates = true"
,但是当我尝试打开会话时,我得到了

Opc.Ua.ServiceResultException “证书不可信。 主题名称:[电子邮件受保护] ...”

提前致谢

    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)
        {
        }
        
    }
c# opc-ua
4个回答
0
投票

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

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

您无法使用客户端 AutoAcceptUntrustedCertificates=true 覆盖此设置。


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; };
}

它对我来说适用于多个不同的服务器。


-1
投票

我想在 VB.net 中执行此操作,但出现错误:

    config.Validate(ApplicationType.Client).GetAwaiter().GetResult()
    If config.SecurityConfiguration.AutoAcceptUntrustedCertificates Then
        AddHandler config.CertificateValidator.CertificateValidation, Sub(s, e) e.Accept = e.Error.StatusCode = StatusCodes.BadCertificateUntrusted
    End If

Lambda 参数 '' 隐藏封闭块中的变量、先前定义的范围变量或查询表达式中隐式声明的变量。

© www.soinside.com 2019 - 2024. All rights reserved.