Api 为什么不是';t Opc.Ua.UserIdentity是否将密码干净地发送到Opc服务器?

Api 为什么不是';t Opc.Ua.UserIdentity是否将密码干净地发送到Opc服务器?,api,opc-ua,Api,Opc Ua,我对UserIdentity(用户,密码)构造函数有问题。 我的密码是4个字符长。当密码到达服务器时,密码长度为36个字符。前4个字符是我的密码,其余的是随机垃圾 Opc.Ua.Client.dll和Opc.Ua.Core.dll的版本为1.0.238.1 是什么原因导致了这种情况?我该如何正确发送密码 更新 ApplicationConfiguration configuration = Helpers.CreateClientConfiguration(); X509Certificate2

我对UserIdentity(用户,密码)构造函数有问题。 我的密码是4个字符长。当密码到达服务器时,密码长度为36个字符。前4个字符是我的密码,其余的是随机垃圾

Opc.Ua.Client.dll和Opc.Ua.Core.dll的版本为1.0.238.1

是什么原因导致了这种情况?我该如何正确发送密码

更新

ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();
X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();
configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
EndpointDescription endpointDescription = Helpers.CreateEndpointDescription(Url);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);
endpointConfiguration.OperationTimeout = 300000;
endpointConfiguration.UseBinaryEncoding = true;
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
BindingFactory bindingFactory = BindingFactory.Create(configuration);

if (endpoint.UpdateBeforeConnect)
{
    endpoint.UpdateFromServer(bindingFactory); 
    endpointDescription = endpoint.Description;
    endpointConfiguration = endpoint.Configuration;
}

SessionChannel channel = SessionChannel.Create(
    configuration,
    endpointDescription,
    endpointConfiguration,
    bindingFactory,
    clientCertificate,
    null);

m_Session = new Session(channel, configuration, endpoint);
m_Session.ReturnDiagnostics = DiagnosticsMasks.All;

m_Session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
m_Session.Notification += new NotificationEventHandler(m_Session_Notification);

UserIdentity identity;
if (userName == null || userName.Length == 0)
{
    identity = new UserIdentity();
}
else
{
    identity = new UserIdentity(userName, password);
}

m_Session.Open("ATF UA client", identity);
log.Debug("Connect ok");

其余的根本不是垃圾。它应与CreateSessionResponse中发送给OPC UA客户端的服务器相同

根据OPC UA规范,UserIdentityToken加密格式为:

  • 长度-字节[4]=>密码的长度
  • 令牌数据-字节[*]=>您的密码
  • ServerNonce-字节[*]
密码长度为36字节,因为OPC UA服务器主要使用32字节的ServerNonce,而您的密码长度为4字节


您还应该验证使用该UserIdentityToken发送的ServerNonce是否与您在CreateSessionResponse中提供的相同。

其余部分根本不是垃圾。它应与CreateSessionResponse中发送给OPC UA客户端的服务器相同

根据OPC UA规范,UserIdentityToken加密格式为:

  • 长度-字节[4]=>密码的长度
  • 令牌数据-字节[*]=>您的密码
  • ServerNonce-字节[*]
密码长度为36字节,因为OPC UA服务器主要使用32字节的ServerNonce,而您的密码长度为4字节


您还应该验证使用该UserIdentityToken发送的ServerNonce是否与您在CreateSessionResponse中提供的相同。

谢谢您提供的信息。我使用的是C#API,我只能假设库正确处理ServerNonce。我已在问题中添加了一部分代码。如果您正在编写服务器,则需要验证客户端是否使用密码添加了CreateSessionResponse中提供的ServerNonce。如果您正在编写客户端,则必须将服务器返回的ServerNonce与您的密码附加在一起……您是否有机会查看我发布的代码?我的猜测是,直到最后一行才与服务器进行通信,那么我从哪里获取ServerNonce呢?当然,这应该发生在图书馆里。我把DLL作为西门子软件包的一部分,它们似乎起源于OPC基金会。我已经搜索了这些LIB,但没有找到任何文档。再次感谢你的帮助!我看了一眼,但真的不明白它应该做什么。。。如果您收到一个密码并想要检查它,这意味着您在服务器端,您收到了一个ActivateSessionRequest。因此,这也意味着在此之前,您得到了一个CreateSessionRequest,并使用包含ServerNonce的CreateSessionResponse进行响应。因此,只需检查您使用密码接收的数据是否与password+ServerNonce相同。如果是垃圾数据,请检查您是否在CreateSessionResponsed中发送了一个ServerNonce,是否有OPC UA规范?-检查5.6.2 CreateSession、5.6.3 ActivateSession和7.35 UserIdentityToken参数谢谢提供信息。我使用的是C#API,我只能假设库正确处理ServerNonce。我已在问题中添加了一部分代码。如果您正在编写服务器,则需要验证客户端是否使用密码添加了CreateSessionResponse中提供的ServerNonce。如果您正在编写客户端,则必须将服务器返回的ServerNonce与您的密码附加在一起……您是否有机会查看我发布的代码?我的猜测是,直到最后一行才与服务器进行通信,那么我从哪里获取ServerNonce呢?当然,这应该发生在图书馆里。我把DLL作为西门子软件包的一部分,它们似乎起源于OPC基金会。我已经搜索了这些LIB,但没有找到任何文档。再次感谢你的帮助!我看了一眼,但真的不明白它应该做什么。。。如果您收到一个密码并想要检查它,这意味着您在服务器端,您收到了一个ActivateSessionRequest。因此,这也意味着在此之前,您得到了一个CreateSessionRequest,并使用包含ServerNonce的CreateSessionResponse进行响应。因此,只需检查您使用密码接收的数据是否与password+ServerNonce相同。如果是垃圾数据,请检查您是否在CreateSessionResponsed中发送了一个ServerNonce,是否有OPC UA规范?-检查5.6.2 CreateSession、5.6.3 ActivateSession和7.35 UserIdentityToken参数