セキュリティ対応OPC UAクライアントの作成
OPC UAのコア機能の1つは、セキュリティのサポートです。つまり、暗号化され署名されたプロトコル、ユーザー認証、認可がサポートされています。
この機能を実現するためには、各アプリケーション・インスタンス(プログラムのインストール)が独自のApplication Instance Certificate
、それに応じた秘密鍵を持つ必要があります。
アプリケーションは、自分で自己署名証明書を生成することも、OPC UA GDSを使用して認証局から証明書を取得することも、ユーザーが手動で作成した証明書で構成することもできます。
現時点では、Qt OPC UA は証明書の生成や GDS をサポートしていないため、このチュートリアルでは、OpenSSL を使用してコマンドラインで自己署名の OPC UA 証明書を生成する方法を説明します。
新しいアプリケーション証明書の作成
OPC UA に必要なすべての拡張子を持つ正しい x509v3 証明書を生成できるようにするには、まず必要なすべての情報を含む設定ファイルをセットアップする必要があります。
subject
、subjectAltName
をケースに合わせて変更することを忘れないでください。
subjectAltName
のURI
フィールドにアプリケーションのApplicationURI
を挿入し、subjectAltName
のDNS
フィールドに PC またはデバイスのホスト名を挿入することが重要です。また、デバイスがホスト名をサポートしておらず、静的 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, dataEncipherment extendedKeyUsage = clientAuth 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アプリケーションの設定
前の手順で作成した証明書でセキュリティを動作させるには、以下のことが重要である。
- 正しいアプリケーションIDを構成する
m_identity = m_pkiConfig.applicationIdentity();
- SDKが証明書、秘密鍵、トラストリストなどを見つけられるように、PKIロケーションを構成する。
例えば、Qt OPC UA Viewer Example のコードを参照:
voidMainWindow::setupPkiConfiguration() {constQDirpkidir=QDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+ "/pki");if(!pkidir.exists()&& !copyDirRecursively(":/pki",pkidir.path())) qFatal("Could not set up directory %s!", qUtf8Printable(pkidir.path())); m_pkiConfig.setClientCertificateFile(pkidir.absoluteFilePath("own/certs/opcuaviewer.der")); m_pkiConfig.setPrivateKeyFile(pkidir.absoluteFilePath("own/private/opcuaviewer.pem")); m_pkiConfig.setTrustListDirectory(pkidir.absoluteFilePath("trusted/certs")); m_pkiConfig.setRevocationListDirectory(pkidir.absoluteFilePath("trusted/crl")); m_pkiConfig.setIssuerListDirectory(pkidir.absoluteFilePath("issuers/certs")); m_pkiConfig.setIssuerRevocationListDirectory(pkidir.absoluteFilePath("issuers/crl"));constQStringListtoCreate={ m_pkiConfig.issuerListDirectory(),m_pkiConfig.issuerRevocationListDirectory() };for(constQString&dir: toCreate) {if(!QDir().mkpath(dir)) qFatal("Could not create directory %s!", qUtf8Printable(dir)); } }
この例では、Qtリソースシステムから、事前に設定された自己証明書と信頼済み証明書をファイルシステム内の書き込み可能な場所に展開します。残りの発行者(失効)リスト用のディレクトリは手動で作成します。
PKI フォルダのレイアウト
Qt OPC UA では、以下のフォルダ・レイアウトを使用します:
フォルダ | 説明 |
---|---|
自身の | アプリケーション自身の証明書を格納する場所。 |
trusted | 信頼できるアプリケーション証明書または信頼できるCA証明書のリスト。 |
発行者 | 信頼されていないが、証明書の署名をチェックするために必要なCAの証明書のリスト。 |
拒否 | ここでアプリケーションは拒否された証明書を保存し、後に管理者が信頼できるようにする。ここにファイルの最大数を設定することが重要である。この数に達した場合、最も古いファイルから削除される。制限を設けないと、攻撃者がマシンのハード・ディスクを無効な接続試行で一杯にする可能性がある。 |
own
、trusted
、issuers
の各フォルダには、以下の表で定義されるサブディレクトリ構造が含まれる。
サブディレクトリ | 説明 |
---|---|
certs | DER エンコードされた X.509 v3 証明書が格納される。ファイルの拡張子は .der とする。 |
プライベート | 秘密鍵。ファイルの形式はバックエンドに依存する。PEM エンコードされたファイルの拡張子は .pem である。PKCS#12 エンコードされたファイルには、.pfx 拡張子を付ける。ルート・ファイル名は、certs ディレクトリ内の対応する公開鍵ファイルと同じでなければならない。このフォルダは、own フォルダの中にのみ存在する。 |
crl | certsディレクトリにあるすべてのCA証明書のDERエンコードされたCRLが含まれる。ファイルの拡張子は .crl とする。 |
最初の接続
初めて接続する場合、クライアントはサーバー証明書を信頼する必要がある。
クライアントは証明書の警告(証明書の詳細)を表示し、証明書を信頼リストに保存できるようにする必要があります。例については、Qt OPC UA Viewer Exampleを参照のこと。
クライアントがサーバ証明書を受け入れたら、再度接続を試みることができる。このとき、サーバはクライアントの証明書を拒否することがあります。これは、一般的なエラー・コードBadSecurityChecksFailed
で示されます。サーバーは通常、拒否された証明書を特別なフォルダ(rejected
)に保存します。管理者は、これらを信頼リストに移動してクライアントを信頼することができます。これにより、手動でクライアント証明書をサーバー・マシンにコピーする必要がなくなります。
サーバーがクライアントを信頼すると、すぐにセキュリティで接続できるようになります。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.