java - 如何接受/查找来自 opc ua 服务器的证书?

标签 java certificate opc-ua

我是 opc ua 的新手,不是 java 专家。在 java 中设置客户端时,我在处理证书时遇到了问题。我想通过 Basic 256、SignAndEncrypt 连接到服务器。据我了解,在这个安全阶段,由客户端创建或加载的证书将发送到必须接受的服务器。服务器然后将证书发回客户端,然后客户端需要接受该证书。请纠正我,如果我错了。

在客户端创建/加载证书并将其发送到服务器已经可以正常工作(参见下面的代码),然后我可以在服务器端手动接受它。但在那之后我陷入了困境:如何在我的代码中看到此证书验证以及如何找到服务器证书,更不用说接受它了? 我在实现过程中使用了opc ua的SampleConsoleClient进行一些定位。但与那里相反,我不使用任何用户输入。

这是我到目前为止的一些代码。

初始化:

try {
        client = new UaClient(serverUri);
    } catch (final URISyntaxException e) {
        throw new InitializationException("The server uri has an invalid syntax.", e);
    }
    try {
        client.setApplicationIdentity(createApplicationIdentity());
    } catch (final SecureIdentityException e) {
        throw new InitializationException(
                "Application Identity could not be created due to a Security Identity Exception.", e);
    } catch (final IOException e) {
        throw new InitializationException("Application Identity could not be created due to an IO Exception.",
                e);
    }

创建应用程序身份():

final ApplicationDescription appDescription = new ApplicationDescription();
    appDescription.setApplicationName(new LocalizedText(APPLICATION_NAME, Locale.ENGLISH));
    appDescription.setApplicationUri(APPLICATION_URI);
    appDescription.setProductUri(PRODUCT_URI);
    appDescription.setApplicationType(ApplicationType.Client);

    // Setting security features
    client.setSecurityMode(SecurityMode.BASIC256_SIGN_ENCRYPT);
    client.setCertificateValidator(validator);
    validator.setValidationListener(myValidationListener); //myValidationListener is similar to most lines in MyCertificateValidationListener in the opc ua samples
    final File privatePath = new File(validator.getBaseDir(), "private");
    final KeyPair issuerCertificate = null;
    final int[] keySizes = null;
    final ApplicationIdentity identity = ApplicationIdentity.loadOrCreateCertificate(appDescription,
            "Sample Organisation", "opcua", privatePath, issuerCertificate, keySizes, true);
    identity.setApplicationDescription(appDescription);
    return identity; 

初始化后,我尝试这样连接(带注释,我想象连接如何正常工作):

final String securityPolicy = client.getEndpoint() == null
            ? client.getSecurityMode().getSecurityPolicy().getPolicyUri()
                    : client.getEndpoint().getSecurityPolicyUri();

            client.setSessionName(String.format("%s@%s/Session%d", APPLICATION_NAME,
                    ApplicationIdentity.getActualHostNameWithoutDomain(), ++sessionCount));
            try {
                //Idea: catch the server certificate and accept it. Only if that was possible: connect
                client.connect();
            } catch (final ServiceException e) {
                e.printStackTrace();
            }
            client.setKeepSubscriptions(false);
            // After that resolving namespace index (works fine)
            }

以及抛出的错误:

WARN  (?:?): /<IPofServer> Error org.opcfoundation.ua.common.ServiceResultException: Bad_SecurityChecksFailed
(0x80130000) "An error occurred verifying security." at
org.opcfoundation.ua.transport.tcp.io.TcpConnection$ReadThread.run(Unknown Source)
com.prosysopc.ua.client.ConnectException: Failed to create secure channel to server: : opc.tcp://<IPofServer>
[http://opcfoundation.org/UA/SecurityPolicy#Basic256,SignAndEncrypt]
ServiceResult=Bad_SecurityChecksFailed (0x80130000) "An error occurred verifying security."
at com.prosysopc.ua.client.UaClient.n(Unknown Source)
at com.prosysopc.ua.client.UaClient.connect(Unknown Source)
at *lineOfCode*
Caused by: org.opcfoundation.ua.common.ServiceResultException:
Bad_SecurityChecksFailed (0x80130000) "An error occurred verifying security."
at org.opcfoundation.ua.transport.tcp.io.TcpConnection$ReadThread.run(Unknown Source)

lineOfCodeclient.connect()

在此先感谢您的帮助!!

最佳答案

服务器会将它的证书发送给客户端。然后客户端必须

  1. 验证证书的有效性。这相当于验证证书的签名、检查有效性、证书中的主机名是否与端点中的主机名匹配、检查 CRL 等。通常 SDK( validator )应该为您执行此操作,但您可能需要将一些参数提供给 validator ,以实际执行哪些检查。当然,安全策略 Basic256 对证书应满足的证书施加了一些最低要求。您可以在此处查看要求:http://opcfoundation-onlineapplications.org/profilereporting/ -- 转到安全类别 -> Facets -> 安全策略。
  2. 检查服务器证书是否可信。这通常相当于检查(公共(public) key )证书的副本是否已放入某个被选为信任库的证书库中。如果您编写客户端,则由您决定选择哪个商店,但您需要告诉 validator 去哪里查找。我不太了解 Java 中的 OPc UA 开发,但您应该检查 validator 期望存储哪个证书。也许有一个默认的 key 文件。

(在服务器端,客户端证书也会发生同样的情况)。

这假设您从自签名证书开始。如果您使用由 CA 签名的证书,则两个应用程序(服务器和客户端)都需要能够验证另一方的整个链。它可以存储在一些商店本地,也可以由对方发送。链中至少有一个证书必须是最受信任的(必须放入信任库)。

有关 UA 安全性如何工作的一般描述,请查看此链接: https://opcfoundation.org/wp-content/uploads/2014/08/11_OPC_UA_Security_How_It_Works.pdf

有关详细说明,您应该查阅 GitHub 上的规范。

编辑:可能对此处有帮助的补充说明:您似乎正在使用某些 SDK 来达到相关目的。虽然证书验证(即进行签名检查等)通常包含在此类 SDK 中,但应用程序的配置是应用程序(程序员)的任务。这包括您存储可信证书的位置以及您在哪里以及如何收集证书链中缺失的部分。您可能首先尝试检查演示客户端和服务器如何处理此任务,换句话说,通过尝试创建从 UA Expert 到 OPC 基金会示例服务器的安全连接来检查此类应用程序的配置任务。在 OPC 基金会的 .Net SDK 中,信任存储的位置默认为文件系统中的某个目录(C:\ProgramData\OpcFoundation 的子文件夹,仅限 Windows)。但是,您可以在初始化 validator 时覆盖它。其他客户端使用自己的目录结构来存储可信证书

关于java - 如何接受/查找来自 opc ua 服务器的证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45103558/

相关文章:

java - 如何验证第一个静态方法中调用了第二个静态方法?

java - 添加到数组的最小可能值?

spring - Spring HTTP 调用程序的 TLS/SSL 配置

java - 如何通过Java程序连接opc kepware服务器,无需用户名和密码?

.net - 使用 opc ua .net 库在 Unity3d 中创建一个非常简单的 OPC 客户端

c# - 如何使用基于 uaExpert 的客户端连接到需要基于 x509 证书的用户身份验证的 OPC-UA 服务器

java - GWT DateBox - 禁用特定日期

java - Spock 认为测试类的内部枚举应该是 Spec 的属性

php - 如何从证书中获取签名算法?

java - 如何将多个信任库路径添加到 “java.net.ssl.trustStore” ?