我正在使用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 真的很陌生。 有人知道如何正确实现证书通信吗?我还需要为每个用户创建一个证书,这样我就可以验证和识别每个用户来跟踪客户活动。
我希望你能帮忙,我被困住了
您需要将客户端公共证书(.der)存储到服务器的信任文件夹中。
这应该是 server\PKI rusted 或 server\PKI ruste