创建OPC UA会话时遭遇‘Certificate Not Trusted’错误求助
OPC UA客户端连接时出现“Certificate Not Trusted”错误的排查解决
我是OPC UA协议新手,正在对接客户的OPC UA服务器。用C#开发客户端,通过OpenSSL生成客户端证书并交给客户放入信任证书文件夹,但每次尝试连接时,会话创建后都会触发Certificate Not Trusted错误,更换多个证书仍未解决问题。
客户端代码
using System; using System.Security.Cryptography.X509Certificates; using Opc.Ua; using Opc.Ua.Client; using System.Threading; using System.Threading.Tasks; class Program { private async Task<object> ReadVariableAsync(Session session, NodeId nodeId, CancellationToken cancellationToken = default) { ReadValueId readValueId = new ReadValueId { NodeId = nodeId, AttributeId = Attributes.Value }; ReadResponse readResponse = await session.ReadAsync( null, 0, TimestampsToReturn.Both, new[] { readValueId }, cancellationToken ); if (readResponse != null && readResponse.Results != null && readResponse.Results.Count > 0 && StatusCode.IsGood(readResponse.Results[0].StatusCode)) { Console.WriteLine($"Value of MyVariable: {readResponse.Results[0].Value}"); return readResponse.Results[0].Value; } else { Console.WriteLine("Failed to read the variable value."); return false; } } private async Task<bool> WriteVariableAsync(Session session, NodeId nodeId, object value, CancellationToken cancellationToken = default) { try { WriteValue writeValue = new WriteValue { NodeId = nodeId, AttributeId = Attributes.Value, Value = new DataValue(new Variant(value)), }; WriteValueCollection writeValues = new WriteValueCollection { writeValue }; WriteResponse writeResponse = await session.WriteAsync( null, writeValues, cancellationToken ); if (writeResponse != null && writeResponse.Results != null && writeResponse.Results.Count > 0 && StatusCode.IsGood(writeResponse.Results[0])) { Console.WriteLine("Write operation successful."); return true; } else { Console.WriteLine("Failed to write to the variable."); return false; } } catch (Exception ex) { Console.WriteLine($"Error during write operation: {ex.Message}"); return false; } } static async Task Main() { string endpointUrl = "opc.tcp://xx.xx.xx"; string username = "xxxx"; string password = "xxxx"; UserIdentity userIdentity = new UserIdentity(username, password); X509Certificate2 certificate = new X509Certificate2(@"C:\xxxx\xxxx.der"); ApplicationConfiguration config = new ApplicationConfiguration { ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000, }, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { Certificate = certificate, }, AutoAcceptUntrustedCertificates = true, RejectSHA1SignedCertificates = true, }, }; using (var session = await Session.Create(config, new ConfiguredEndpoint(null, new EndpointDescription(endpointUrl)), true, "", 60000, userIdentity, null)) { Program program = new Program(); NodeId nodeId = NodeId.Parse("ns=4;s=xx.xxx.xx .Application.Rx_from_Client.Order"); var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; object value = await program.ReadVariableAsync(session, nodeId, cancellationToken); } } }
OpenSSL证书生成命令
openssl genpkey -algorithm RSA -out client_key.pem openssl req -new -key client_key.pem -out client_csr.pem openssl x509 -req -in client_csr.pem -signkey client_key.pem -out client_cert.pem openssl x509 -req -in client_csr.pem -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out client_cert.pem openssl x509 -in client_cert.pem -outform der -out client_cert.der
排查解决要点
证书加载完整性问题
你当前加载的.der格式证书仅包含公钥,OPC UA客户端需要同时持有公钥和私钥才能完成双向认证。建议用OpenSSL将PEM格式证书和密钥合并为包含私钥的.pfx文件:openssl pkcs12 -export -in client_cert.pem -inkey client_key.pem -out client_cert.pfx然后在代码中加载该文件(需提供导出时设置的密码):
X509Certificate2 certificate = new X509Certificate2(@"C:\xxxx\client_cert.pfx", "你的导出密码");证书生成流程问题
你的命令中第二次openssl x509 -req(CA签名)会覆盖第一次自签名的证书,确认客户信任的是CA签名后的最终证书。同时检查客户是否已将CA证书导入到服务器的信任根证书库中。OPC UA配置补充
现有配置缺少应用标识和证书验证回调,补充以下内容:config.ApplicationName = "你的客户端应用名称"; config.ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:你的客户端应用名称"; // 测试环境临时跳过服务器证书验证,生产环境需严格校验 config.CertificateValidator.CertificateValidation += (sender, e) => { e.Accept = true; };注意:
AutoAcceptUntrustedCertificates仅控制客户端是否接受服务器的未信任证书,不影响服务器对客户端证书的验证,无法解决当前问题。服务器端信任配置验证
确认客户已将你的客户端证书放入服务器的信任客户端证书目录(部分服务器会区分根证书和客户端证书文件夹),同时检查服务器是否启用了客户端证书强制验证,以及证书的有效期、主体名称是否符合服务器要求。
内容的提问来源于stack exchange,提问作者Jacopo SDG
相关产品推荐
相关产品推荐

