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

r8uurelv  于 2021-07-09  发布在  Java
关注(0)|答案(3)|浏览(798)

我是opc ua的新手,不是java的Maven。在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);
    }

createapplicationidentity():

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)

代码行是 client.connect() .
提前谢谢你的帮助!!

izj3ouym

izj3ouym1#

谢谢大家的回答。在此期间,我基本上尝试了复制/粘贴和修改 connect() 以及 initalize() prosyssdk示例中sampleconsoleclient中的方法。我猜这和更新一些信息有关,但我不太确定。。。事实上,我的申请正在进行中,但谢谢你的努力!

omvjsjqw

omvjsjqw2#

很明显,您指的是prosys opc ua java sdk。
当您第一次尝试建立安全连接时,通常首先发生的是,服务器将拒绝访问您的客户端应用程序,并返回bad\u securitychecksfiled。
只有在告诉服务器信任(客户机应用程序的证书)之后,才能进入客户机应用程序将尝试验证服务器证书的阶段,并触发“validationlistener”。

iyr7buue

iyr7buue3#

服务器将把它的证书发送给客户端。然后客户必须
验证证书的有效性。这相当于验证证书的签名、检查有效性、证书中的主机名是否与端点中的主机名匹配、检查crl等等。通常sdk(验证器)应该为您完成这项工作,但是您可能需要向验证器提供一些参数,以便实际执行哪些检查。安全策略basic256对证书施加了一些最低要求,当然,证书应该满足这些要求。您可以在此处查看要求:http://opcfoundation-onlineapplications.org/profilereporting/ --转到安全类别->面->安全策略。
检查服务器证书是否可信。这通常相当于检查(puclic key)证书的副本是否已放入选择为信任存储的某个证书存储中。如果您编写客户机,则由您决定选择哪个存储,但您需要告诉验证器在哪里查找。我对opc-ua在java中的开发不太了解,但是您应该检查验证器希望存储哪些证书。可能有一个默认的密钥文件。
(在服务器端,客户端证书也是如此)。
这假设您是从自签名证书开始的。如果您使用的是由ca签名的证书,那么两个应用程序(服务器和客户端)都需要能够验证另一方的整个链。它可以本地存储在某个存储中,也可以由另一方发送。链中至少有一个证书必须是最可信的(必须放入信任存储)。
有关ua安全工作原理的一般说明,请查看以下链接:https://opcfoundation.org/wp-content/uploads/2014/08/11_opc_ua_security_how_it_works.pdf
有关详细的帐户,请参阅github上提供的规范。
编辑:一个额外的评论在这里可能会有所帮助:你似乎正在使用一些sdk的目的有问题。虽然证书的验证(即进行签名检查等)通常包含在这样的sdk中,但应用程序的配置是应用程序(程序员)的任务。这包括存储可信证书的位置,以及在何处以及如何收集证书链中缺失的部分。您可能首先要检查客户机和服务器如何处理此任务,换句话说,通过尝试从UAMaven创建安全连接到OPC基金会的示例服务器,检查这些应用程序的配置任务。在OPC基金会的.NETSDK中,信任存储的位置默认为文件系统中的某个目录(子文件夹) C:\ProgramData\OpcFoundation ,仅限windows)。但是,您可以在初始化验证器时覆盖它。其他客户端使用自己的目录结构来存储可信证书

相关问题