opc.foudation opcua

366 阅读4分钟

sha1 key 长度问题

  1. opc.foundation opcua 问题:

Certificate doesn't meet minimum key length requirement

解决方法参考:

Certificate doesn't meet minimum key length requirement · Issue #305 · OPCFoundation/UA-.NETStandard · GitHub

SHA1 signed certificates are not trusted · Issue #306 · OPCFoundation/UA-.NETStandard · GitHub

ApplicationConfiguration.SaveToFile() removes "RejectSHA1SignedCertificates" · Issue #184 · OPCFoundation/UA-.NET-Leg…

ApplicationConfiguration.SaveToFile() removes "RejectSHA1SignedCertificates" #184 · Issue #930 · OPCFoundation/UA-.NETStan…

代码配置如下:

        //新增用于兼容sha1
        private static ApplicationConfiguration CreateClientConfigurationSha1()
        {
            ApplicationConfiguration configuration = new ApplicationConfiguration();

            configuration.ApplicationName = "Sinumerik Opc Ua Client";
            configuration.ApplicationType = ApplicationType.Client;
            configuration.ApplicationUri = "urn:MyClient"; //Kepp this syntax
            configuration.ProductUri = "SiemensAG.IndustryOnlineSupport";

            configuration.SecurityConfiguration = new SecurityConfiguration();
            configuration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier();
            configuration.SecurityConfiguration.ApplicationCertificate.StoreType = CertificateStoreType.X509Store;
            configuration.SecurityConfiguration.ApplicationCertificate.StorePath = "CurrentUser\\My";
            configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = configuration.ApplicationName;

            configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = CertificateStoreType.Directory;
            configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "OPC Foundation/CertificateStores/UA Applications";
            configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = CertificateStoreType.Directory;
            configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities";

            configuration.SecurityConfiguration.RejectedCertificateStore = new CertificateStoreIdentifier();
            configuration.SecurityConfiguration.RejectedCertificateStore.StoreType = CertificateStoreType.Directory;
            configuration.SecurityConfiguration.RejectedCertificateStore.StorePath = "OPC Foundation/CertificateStores/RejectedCertificates";

            configuration.SecurityConfiguration.NonceLength = 32;
            configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;
            configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;


            X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true).Result;

            if (clientCertificate == null)
            {
                List<string> localIps = GetLocalIpAddressAndDns();

                UInt16 keySize = 2048; //must be multiples of 1024
                UInt16 lifeTime = 24; //in month
                UInt16 algorithm = 1; //0 = SHA1; 1 = SHA256
               
                clientCertificate = CertificateFactory.CreateCertificate(
                    configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    string.Empty,           //key
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    string.Empty,          //sub name
                    localIps,
                    keySize,
                    DateTime.Now,           //start time
                    lifeTime,
                    algorithm);
            }

            configuration.TransportQuotas = new TransportQuotas();
            configuration.TransportQuotas.OperationTimeout = 360000;
            configuration.TransportQuotas.MaxStringLength = 67108864;
            configuration.TransportQuotas.MaxByteStringLength = 16777216; //Needed, i.e. for large TypeDictionarys


            configuration.ClientConfiguration = new ClientConfiguration();
            configuration.ClientConfiguration.DefaultSessionTimeout = 360000;

            configuration.Validate(ApplicationType.Client);

            return configuration;

        }
  1. siemens opcua

后续问题:

One or more errors occurred. (Certificate is not trusted.)

image.png

参考:

OPC UA Client BadCertificateUntrusted - 176164 - Industry Support Siemens

修改:opcuaHlperApi 中的方法

部分代码:

#if DEBUG     //此处添加
            configuration.SecurityConfiguration.NonceLength = 32;
            configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;
            configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
#endif

全部代码:

        private static ApplicationConfiguration CreateClientConfiguration()
        {
            // The application configuration can be loaded from any file.
            // ApplicationConfiguration.Load() method loads configuration by looking up a file path in the App.config.
            // This approach allows applications to share configuration files and to update them.
            // This example creates a minimum ApplicationConfiguration using its default constructor.
            ApplicationConfiguration configuration = new ApplicationConfiguration();

            // Step 1 - Specify the client identity.
            //configuration.ApplicationName = "UA Client 1500";
            configuration.ApplicationName = "Sinumerik Opc Ua Client";
            configuration.ApplicationType = ApplicationType.Client;
            configuration.ApplicationUri = "urn:MyClient"; //Kepp this syntax
            configuration.ProductUri = "SiemensAG.IndustryOnlineSupport";

            // Step 2 - Specify the client's application instance certificate.
            // Application instance certificates must be placed in a windows certficate store because that is 
            // the best way to protect the private key. Certificates in a store are identified with 4 parameters:
            // StoreLocation, StoreName, SubjectName and Thumbprint.
            // When using StoreType = Directory you need to have the opc.ua.certificategenerator.exe installed on your machine

            configuration.SecurityConfiguration = new SecurityConfiguration();
            configuration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier();
            configuration.SecurityConfiguration.ApplicationCertificate.StoreType = CertificateStoreType.X509Store;
            configuration.SecurityConfiguration.ApplicationCertificate.StorePath = "CurrentUser\\My";
            configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = configuration.ApplicationName;
            configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = true;
            configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;

            // Define trusted root store for server certificate checks
            configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = CertificateStoreType.X509Store;
            configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "CurrentUser\\Root";
            configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = CertificateStoreType.X509Store;
            configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "CurrentUser\\Root";

#if DEBUG     //此处添加
            configuration.SecurityConfiguration.NonceLength = 32;
            configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;
            configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
#endif

            // find the client certificate in the store.
            Task<X509Certificate2> clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

            // create a new self signed certificate if not found.
            if (clientCertificate.Result == null)
            {
                CreateCertificateAndAddToStore(configuration.ApplicationUri, configuration.ApplicationName, configuration.SecurityConfiguration.ApplicationCertificate.StoreType, configuration.SecurityConfiguration.ApplicationCertificate.StorePath);
            }

            // Step 3 - Specify the supported transport quotas.
            // The transport quotas are used to set limits on the contents of messages and are
            // used to protect against DOS attacks and rogue clients. They should be set to
            // reasonable values.
            configuration.TransportQuotas = new TransportQuotas();
            configuration.TransportQuotas.OperationTimeout = 360000;
            configuration.TransportQuotas.SecurityTokenLifetime = 86400000;
            configuration.TransportQuotas.MaxStringLength = 67108864;
            configuration.TransportQuotas.MaxByteStringLength = 16777216; //Needed, i.e. for large TypeDictionarys

            // Step 4 - Specify the client specific configuration.
            configuration.ClientConfiguration = new ClientConfiguration();
            configuration.ClientConfiguration.DefaultSessionTimeout = 360000;

            // Step 5 - Validate the configuration.
            // This step checks if the configuration is consistent and assigns a few internal variables
            // that are used by the SDK. This is called automatically if the configuration is loaded from
            // a file using the ApplicationConfiguration.Load() method.
            _ = configuration.Validate(ApplicationType.Client);

            return configuration;
        }

连接结果:

image.png

image.png

image.png

  1. opcua 做成windows服务,证书被拒绝

异常原因:

  • bat制作的windows服务,默认已system用户登录,但opcua client中的证书设置路径为 "CurrentUser\Root"
 private static ApplicationConfiguration CreateClientConfiguration(bool sha1 = false)
 {
     // The application configuration can be loaded from any file.
     // ApplicationConfiguration.Load() method loads configuration by looking up a file path in the App.config.
     // This approach allows applications to share configuration files and to update them.
     // This example creates a minimum ApplicationConfiguration using its default constructor.
     ApplicationConfiguration configuration = new ApplicationConfiguration();

     // Step 1 - Specify the client identity.
     //configuration.ApplicationName = "UA Client 1500";
     configuration.ApplicationName = "Sinumerik Opc Ua Client";
     configuration.ApplicationType = ApplicationType.Client;
     configuration.ApplicationUri = "urn:MyClient"; //Kepp this syntax
     configuration.ProductUri = "SiemensAG.IndustryOnlineSupport";

     // Step 2 - Specify the client's application instance certificate.
     // Application instance certificates must be placed in a windows certficate store because that is 
     // the best way to protect the private key. Certificates in a store are identified with 4 parameters:
     // StoreLocation, StoreName, SubjectName and Thumbprint.
     // When using StoreType = Directory you need to have the opc.ua.certificategenerator.exe installed on your machine

     configuration.SecurityConfiguration = new SecurityConfiguration();
     configuration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier();
     configuration.SecurityConfiguration.ApplicationCertificate.StoreType = CertificateStoreType.X509Store;
     configuration.SecurityConfiguration.ApplicationCertificate.StorePath = "CurrentUser\\My";
     configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = configuration.ApplicationName;
     configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = true;
     configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;

     // Define trusted root store for server certificate checks
     configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = CertificateStoreType.X509Store;
     configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "CurrentUser\\Root";
     configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = CertificateStoreType.X509Store;
     configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "CurrentUser\\Root";

     //此处 开启 sha1 证书
     if (sha1)
     {
         configuration.SecurityConfiguration.NonceLength = 32;
         configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;
         configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
         configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
     }


     // find the client certificate in the store.
     Task<X509Certificate2> clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

     // create a new self signed certificate if not found.
     if (clientCertificate.Result == null)
     {
         CreateCertificateAndAddToStore(configuration.ApplicationUri, configuration.ApplicationName, configuration.SecurityConfiguration.ApplicationCertificate.StoreType, configuration.SecurityConfiguration.ApplicationCertificate.StorePath);
     }

     // Step 3 - Specify the supported transport quotas.
     // The transport quotas are used to set limits on the contents of messages and are
     // used to protect against DOS attacks and rogue clients. They should be set to
     // reasonable values.
     configuration.TransportQuotas = new TransportQuotas();
     configuration.TransportQuotas.OperationTimeout = 360000;
     configuration.TransportQuotas.SecurityTokenLifetime = 86400000;
     configuration.TransportQuotas.MaxStringLength = 67108864;
     configuration.TransportQuotas.MaxByteStringLength = 16777216; //Needed, i.e. for large TypeDictionarys

     // Step 4 - Specify the client specific configuration.
     configuration.ClientConfiguration = new ClientConfiguration();
     configuration.ClientConfiguration.DefaultSessionTimeout = 360000;

     // Step 5 - Validate the configuration.
     // This step checks if the configuration is consistent and assigns a few internal variables
     // that are used by the SDK. This is called automatically if the configuration is loaded from
     // a file using the ApplicationConfiguration.Load() method.
     _ = configuration.Validate(ApplicationType.Client);

     return configuration;
 }
  • 找不到证书,故报错 image.png

解决方法:

  • 手动设置将服务的system账户切换为本机账户
  1. 停止服务
  2. 转到服务,切换登录用户至当前用户

image.png

image.png

  1. bat处理的方式,设置用户
sc create %serviceName%  BinPath= %serviceFilePath% start= auto obj=用户名  password=密码

opcua 证书问题参考:

将 OPC UA 服务器实现为 Windows 后台服务 ·期刊 #1007 ·OPCFoundation/UA-。NETS标准 ·GitHub的

bat windows 服务参考:

sc.exe create | Microsoft Learn

证书

  1. 第一次运行程序:提示安装证书

d70c23dbedef8364890a204e1240668.png

证书问题

  1. windows 上查看证书

c# 代码,赋值证书, UAClientHelperAPI.cs

private static ApplicationConfiguration CreateClientConfiguration()
{
	ApplicationConfiguration applicationConfiguration = new ApplicationConfiguration();
	applicationConfiguration.ApplicationName = "Sinumerik Opc Ua Client";
	applicationConfiguration.ApplicationType = ApplicationType.Client;
	applicationConfiguration.ApplicationUri = "urn:MyClient";
	applicationConfiguration.ProductUri = "SiemensAG.IndustryOnlineSupport";
	applicationConfiguration.SecurityConfiguration = new SecurityConfiguration();
	applicationConfiguration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier();
	applicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType = "Windows";
	applicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath = "CurrentUser\\My";
	applicationConfiguration.SecurityConfiguration.ApplicationCertificate.SubjectName = applicationConfiguration.ApplicationName;
	applicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = "Windows";
	applicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "CurrentUser\\Root";
	applicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StoreType = "Windows";
	applicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "CurrentUser\\Root";
	X509Certificate2 x509Certificate = applicationConfiguration.SecurityConfiguration.ApplicationCertificate.Find(true);
	bool flag = x509Certificate == null;
	if (flag)
	{
		List<string> localIpAddressAndDns = UAClientHelperAPI.GetLocalIpAddressAndDns();
		ushort keySize = 2048;
		ushort lifetimeInMonths = 24;
		ushort algorithm = 1;
		x509Certificate = CertificateFactory.CreateCertificate(applicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType, applicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath, applicationConfiguration.ApplicationUri, applicationConfiguration.ApplicationName, null, localIpAddressAndDns, keySize, lifetimeInMonths, algorithm);
	}
	applicationConfiguration.TransportQuotas = new TransportQuotas();
	applicationConfiguration.TransportQuotas.OperationTimeout = 360000;
	applicationConfiguration.TransportQuotas.MaxStringLength = 67108864;
	applicationConfiguration.TransportQuotas.MaxByteStringLength = 16777216;
	applicationConfiguration.ClientConfiguration = new ClientConfiguration();
	applicationConfiguration.ClientConfiguration.DefaultSessionTimeout = 360000;
	applicationConfiguration.Validate(ApplicationType.Client);
	return applicationConfiguration;
}

certmgr.msc

image.png