Создание клиентов OPC UA с поддержкой безопасности
Одной из ключевых функций OPC UA является поддержка безопасности, которая обеспечивает криптографически зашифрованный и подписанный протокол, поддержку аутентификации и авторизации пользователей.
Для этого каждый экземпляр приложения (установка программы) должен иметь свой Application Instance Certificate и соответствующий закрытый ключ.
Приложения могут либо генерировать собственные самоподписанные сертификаты, получать их от центра сертификации с использованием OPC UA GDS, либо просто настраиваться с сертификатами, созданными вручную пользователем.
Поскольку в данный момент Qt OPC UA не поддерживает генерацию сертификатов или GDS, в этом руководстве описывается, как сгенерировать самоподписанный сертификат OPC UA в командной строке с помощью OpenSSL.
Создание нового сертификата приложения
Для создания правильного сертификата x509v3 с необходимыми расширениями для OPC UA, необходимо сначала настроить файл конфигурации со всей необходимой информацией.
Не забудьте изменить subject и subjectAltName в соответствии с вашим случаем.
Важно вставить ApplicationURI приложения в поле URI файла subjectAltName, а имя хоста вашего ПК или устройства в поля DNS файла subjectAltName. В качестве альтернативы, вы можете использовать поле IP если ваше устройство не поддерживает имена хостов и вы работаете со статическими IP-адресами. Будущие версии Qt OPC UA смогут генерировать сертификат за вас с правильной информацией. Пока вы можете создать его с помощью инструмента командной строки OpenSSL.
Пример: opcuaviewer.config
[ 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 = critical, CA:FALSE keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment subjectAltName = URI:urn:foo.com:The%20Qt%20Company:QtOpcUaViewer,DNS:foo.com subjectKeyIdentifier = hash authorityKeyIdentifier=keyid:always,issuer:always [ subject ] countryName = DE stateOrProvinceName = Berlin localityName = Berlin organizationName = The Qt Company commonName = QtOpcUaViewer
Используя этот файл конфигурации, OpenSSL может создать соответствующий сертификат для локального использования.
# create a self-signed certificate and private key openssl req -new -x509 -config opcuaviewer.config -newkey rsa:2048 -keyout opcuaviewer.key -nodes -outform der -out opcuaviewer.der # install the certificate and key into the application PKI directory mv opcuaviewer.der /path/to/application/pki/own/certs/opcuaviewer.der mv opcuaviewer.key /path/to/application/pki/own/private/opcuaviewer.pem # secure private key file permissions chmod 600 /path/to/application/pki/own/private/opcuaviewer.pem
Важно защитить права доступа к файлу с закрытым ключом, чтобы к нему имел доступ только сам процесс UA-приложения. Для служб (демон-процессов) рекомендуется создавать отдельные непривилегированные учетные записи пользователей для этого и назначить этому пользователю владение ключом. Для интерактивных приложений этот ключ должен быть привязан к конкретному пользователю. Для интерактивных приложений также возможно защитить ключ паролем. В этом случае пользователь должен вводить пароль каждый раз, когда приложение запускается и загружает ключ. По этой причине пароли, защищающие ключи, не являются хорошим решением для автономных приложений, так как это потребует хранения пароля в файле конфигурации.
Вы можете вывести данные сертификата с помощью OpenSSL для проверки содержимого сертификата:
openssl x509 -in opcuaviewer.der -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
be:aa:41:79:8a:b0:4f:9a
Signature Algorithm: sha512WithRSAEncryption
Issuer: C = DE, ST = Berlin, L = Berlin, O = The Qt Company, CN = QtOpcUaViewer
Validity
Not Before: Nov 7 14:38:52 2018 GMT
Not After : Dec 7 14:38:52 2018 GMT
Subject: C = DE, ST = Berlin, L = Berlin, O = The Qt Company, CN = QtOpcUaViewer
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
[ skipped ]
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate Sign
X509v3 Subject Alternative Name:
URI:urn:foo.com:The%20Qt%20Company:QtOpcUaViewer, DNS:foo.com
X509v3 Subject Key Identifier:
B2:E8:5E:34:21:EA:67:CF:61:FC:14:94:18:C1:AD:13:89:83:CA:9B
X509v3 Authority Key Identifier:
keyid:B2:E8:5E:34:21:EA:67:CF:61:FC:14:94:18:C1:AD:13:89:83:CA:9B
DirName:/C=DE/ST=Berlin/L=Berlin/O=The Qt Company/CN=QtOpcUaViewer
serial:BE:AA:41:79:8A:B0:4F:9A
Signature Algorithm: sha512WithRSAEncryption
[ skipped ] Настройка приложения UA
Для работы с безопасностью с помощью созданного в предыдущем шаге сертификата важно:
- Настроить правильную идентификацию приложения
m_identity = m_pkiConfig.applicationIdentity();
- Настроить расположение PKI, чтобы SDK мог найти сертификат, закрытый ключ, список доверенных сертификатов и т. д.
void MainWindow::setupPkiConfiguration() { QString pkidir = QCoreApplication::applicationDirPath(); #ifdef Q_OS_WIN pkidir += "../"; #endif pkidir += "/pki"; m_pkiConfig.setClientCertificateFile(pkidir + "/own/certs/opcuaviewer.der"); m_pkiConfig.setPrivateKeyFile(pkidir + "/own/private/opcuaviewer.pem"); m_pkiConfig.setTrustListDirectory(pkidir + "/trusted/certs"); m_pkiConfig.setRevocationListDirectory(pkidir + "/trusted/crl"); m_pkiConfig.setIssuerListDirectory(pkidir + "/issuers/certs"); m_pkiConfig.setIssuerRevocationListDirectory(pkidir + "/issuers/crl"); // create the folders if they don't exist yet createPkiFolders(); }
Структура папок PKI
Qt OPC UA использует следующую структуру папок:
| Папка | Описание |
|---|---|
| own | Расположение для хранения собственных сертификатов приложения. |
| trusted | Список доверенных сертификатов приложения или доверенных сертификатов центров сертификации. |
| issuer | Список сертификатов центров сертификации, которые не являются доверенными, но необходимы для проверки подписей в сертификатах. |
| rejected | Здесь приложение хранит отклоненные сертификаты, чтобы администратор мог их позже доверять. Важно настроить максимальное количество файлов. Если это число достигнуто, сначала удаляется самый старый файл. Без ограничения злоумышленник мог бы заполнить жёсткий диск устройства недействительными подключениями. |
Каждая из папок own, trusted, и issuers содержит подкаталог, определённый в следующей таблице.
| Подкаталог | Описание |
|---|---|
| certs | Содержит DER-кодированные сертификаты X.509 v3. Файлы должны иметь расширение .der. |
| private | Содержит закрытые ключи. Формат файла может зависеть от back-end. Файлы в формате PEM должны иметь расширение .pem. Файлы в формате PKCS#12 должны иметь расширение .pfx. Имя файла должно совпадать с соответствующим файлом открытого ключа в каталоге certs. Этот каталог существует только внутри папки own. |
| crl | Содержит DER-кодированные CRL для сертификатов центров сертификации, найденных в каталогах certs. Файлы должны иметь расширение .crl. |
Первое подключение
При первом подключении клиент должен доверять сертификату сервера.
Клиент должен отобразить предупреждение о сертификате (с подробностями о сертификате) и предложить возможность сохранить сертификат в своём списке доверенных сертификатов. Пример см. в Qt OPC UA Viewer Example.
После того как клиент принял сертификат сервера, можно попробовать подключиться снова. Теперь сервер может отклонить сертификат клиента. Это показано с помощью универсального кода ошибки BadSecurityChecksFailed. Сервер обычно хранит отклоненные сертификаты в специальной папке rejected. Администратор может переместить их в список доверенных сертификатов, чтобы доверять клиентам. Это позволяет избежать ручной копии сертификата клиента на машину сервера.
Как только сервер доверится клиенту, вы сможете подключиться с безопасностью.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/security.html