我正在使用节点操作库来构建OPC UA客户端。我已经使用基本示例连接到OPC-UA服务器(prosys OPC-UA模拟服务器(,但现在我想让我的客户端支持各种身份验证方法。
我能够使用以下代码获得基于用户名+密码的身份验证:
const client = OPCUAClient.create(options);
await client.connect(endpointUrl);
let userIdentity = {type: opcua.UserTokenType.UserName, userName: "bruce", password: "test" };
const session = await client.createSession(userIdentity);
在prosys OPC-UA模拟服务器上;用户名+密码";身份验证方法,并创建匹配的用户。
不过,现在我想让基于X.509证书的用户身份验证工作起来。有没有人在node操作库中有一个工作示例,以及如何使用OpenSSL生成证书的说明?
所以我想通了!以下是其他可能想要它的人(或我未来的自己(的答案
首先,证书似乎需要有正确的用法和扩展。当我生成一个没有这些的证书时,它不起作用。创建一个名为user-key.conf
的文件,其内容类似于:
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = subject
req_extensions = req_ext
x509_extensions = req_ext
string_mask = utf8only
prompt = no
[ req_ext ]
basicConstraints = CA:FALSE
nsCertType = client, server
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign
extendedKeyUsage= serverAuth, clientAuth
nsComment = "Bruces User Cert"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = URI:urn:opcua:user:bruce,IP: 127.0.0.1
[ subject ]
countryName = US
stateOrProvinceName = TX
localityName = Houston
organizationName = AL
commonName = bruce
请注意,在本例中,我正在生成一个自签名证书。我不是安全专家,所以我不知道所有这些声明的含义,也没有测试过哪些声明是绝对必要的。我发现的一些信息似乎表明commonName应该与OPC服务器中的用户名相对应,但这是我在研究中了解到的唯一细节。
接下来,将openssl与此配置文件一起使用,以创建证书和私钥对:
> openssl.exe req -x509 -days 365 -new -out bruce1.pem -keyout bruce1_key.pem -config user-key.conf
出于某种原因(可能是出于安全相关的原因(,openssl强制您指定一个密码短语来保护私钥。到目前为止,我还没有弄清楚如何在node.js中解密它,所以我发现我可以用以下命令删除它:
> openssl.exe rsa -in bruce1_key.pem -out bruce1_key_nopass.pem
然后,至少对于我正在测试的OPC-UA服务器(prosys OPC-UA模拟服务器(,有必要获得.der格式的证书:
> openssl.exe x509 -inform PEM -outform DER -in bruce1.pem -out bruce1.der
此.der文件需要加载到OPC-UA服务器中。对于prosys,这是通过将其复制到.prosys-opc-ua-simulation-serverUSERS_PKICAcerts
文件夹中来完成的。
在node.js中,以下代码将使用生成的证书文件进行连接:
const client = OPCUAClient.create(options);
await client.connect(endpointUrl);
let userIdentity = {
type: UserTokenType.Certificate,
certificateData: fs.readFileSync('./user-certificates/bruce1.pem'),
privateKey: fs.readFileSync('./user-certificates/bruce1_key_nopass.pem','utf8')
}
const session = await client.createSession(userIdentity);
这导致了与prosys OPC-UA客户端的成功连接。我相信未来会有一些改进,比如在node.js.中进行密码解密