如何使用节点库从 opcua 服务器验证客户端证书

问题描述 投票:0回答:1

我正在使用node-opcua创建一个opcua服务器。通过用户和密码进行的用户验证有效,但现在我尝试添加证书,但我不知道该怎么做。

我了解服务器有自己的证书和私钥,每个客户端都有自己的证书。我也知道客户端需要知道服务器的证书,但我不知道服务器如何通过发送的证书来识别每个客户端,服务器将其保存在哪里。

我创建了服务器证书:

    const serverCertificateManager = new OPCUACertificateManager({
        automaticallyAcceptUnknownCertificate: true,
        name: "PKI",
        rootFolder: "./certificates/server/PKI",
        keySize: 2048
    })
    await serverCertificateManager.initialize()

    if (!fs.existsSync(certificateFile)) {

        console.log("Creating self-signed certificate");
    
        await serverCertificateManager.createSelfSignedCertificate({
          applicationUri: `urn:${hostname}:NodeOPCUA-Server`,
          dns: hostname ? [hostname, fqdn] : [fqdn],
          outputFile: certificateFile,
          subject: "/CN=Sterfive/DC=Test",
          startDate: new Date(),
          validity: 365 * 10
        })
      }

并从服务器创建了用户证书:

    const userCertificateManager = new OPCUACertificateManager({
        automaticallyAcceptUnknownCertificate: false,
        name: "UserPki",
        rootFolder: "./certificates/clients/PKI",
        keySize: 2048
    })
    await userCertificateManager.initialize()

这会在

certificates
文件夹中创建一个
clients
和一个
server
文件夹,每个文件夹都有发行者、拥有者、拒绝者和信任者。 在路径
server/PKI/certs/
中,证书和私钥是通过运行上述管理器创建的。并且在
clients
中创建了一些受信任的证书,当我连接没有任何证书(仅使用用户密码)的客户端时,会使用其会话名称创建另一个信任证书。

接下来,我创建了服务器:

    const server = new OPCUAServer({
        port: port,
        serverInfo: {
            applicationName: { text: "Enterprise", locale: "en" },
            applicationUri: `urn:${hostname}:NodeOPCUA-Server`,
            productUri: "NodeOPCUA-Server"
        },
        buildInfo: {
            productName: "Enterprise",
            buildNumber: "1002",
            buildDate: new Date(),
        },
        userManager: {

            isValidUserAsync: function (userName: string, password: string, callback: Callback<boolean>) {
                setImmediate(function () {
                    const authorized = clientsData.some((client:Client )=> client.username === userName && client.password === password)
                    callback(null, authorized);
                })
            },

            getUserRoles: function (user: string): NodeId[] {
                return [makeNodeId(user, 1)];
            }

        },
        serverCertificateManager,
        userCertificateManager,
        certificateFile: certificateFile,
        privateKeyFile: privateKeyFile,
        securityPolicies: [SecurityPolicy.Basic256Sha256],
        securityModes: [MessageSecurityMode.Sign],
        serverCapabilities: {
            maxSessions: 10,
            maxSubscriptionsPerSession: 10,
            maxMonitoredItemsPerSubscription: 30,
            operationLimits: {
                maxNodesPerRead: 10,
                maxNodesPerMethodCall: 10
            }
        },
        maxConnectionsPerEndpoint: 10,
        hostname: hostname,
        allowAnonymous: false
    })

这是我的服务器代码,但是当我尝试使用相同的库连接客户端时,该过程失败。客户端有这个代码:

const client = OPCUAClient.create({
    clientName: username,
    applicationName: username,
    connectionStrategy: connectionStrategy,
    securityMode: MessageSecurityMode.Sign,
    securityPolicy: SecurityPolicy.Basic256Sha256,
    endpointMustExist: true,
    serverCertificate: serverCertificateBuffer,
    certificateFile: certificateFile,
    privateKeyFile: privateKeyFile
});

const session = await client.createSession({
    type: UserTokenType.Certificate,
            certificateData: fs.readFileSync(certificateFile),
            privateKey: fs.readFileSync(privateKeyFile, 'utf-8')
    })

服务器证书是在

server
文件夹中创建的,私钥是创建的 由服务器管理器在
clients
文件夹中创建,并且
certificate
是使用 OPCUACertificateManager 创建的。当我尝试连接到服务器时,客户端抛出此错误:
Error: The connection may have been rejected by server

我怀疑证书实施不起作用,因为我缺少一些东西。我对 opcua 真的很陌生。 有人知道如何正确实现证书通信吗?我还需要为每个用户创建一个证书,这样我就可以验证和识别每个用户来跟踪客户活动。

我希望你能帮忙,我被困住了

node.js openssl x509certificate opc-ua node-opcua
1个回答
1
投票

您需要将客户端公共证书(.der)存储到服务器的信任文件夹中。

这应该是 server\PKI rusted 或 server\PKI ruste

© www.soinside.com 2019 - 2024. All rights reserved.