如何从opc ua服务器接受/查找证书?

时间:2017-07-14 12:54:43

标签: java certificate opc-ua

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

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

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

初​​始化:

modelBuilder.Entity<Order>().HasOptional(e => e.OrderStats).WithRequired(e => e.Order);

createApplicationIdentity():

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

lineOfCode 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)

提前感谢您的帮助!!

3 个答案:

答案 0 :(得分:2)

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

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

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

    有关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)。但是,初始化验证器时,您可以覆盖它。其他客户端使用自己的目录结构来存储可信证书

答案 1 :(得分:0)

您显然是指Prosys OPC UA Java SDK

当您第一次尝试建立安全连接时,首先发生的事情是服务器将拒绝访问您的客户端应用程序 - 并返回Bad_SecurityChecksFailed。

只有在您告知服务器信任(您的客户端应用程序的证书)后,您才会进入客户端应用程序将尝试验证服务器证书的阶段 - 并且将触发您的'validationListener'。 / p>

答案 2 :(得分:0)

谢谢大家的回答。在此期间,我尝试基本复制/粘贴并修改Prosys SDK示例中的SampleConsoleClient中的connect()initalize()方法。猜测它与更新一些信息有关,但我不太确定......事实上,我的应用程序现在正在运行,但感谢您的努力!