Qtの基礎 - パケット

提供:MochiuWiki : SUSE, EC, PCB
2023年2月11日 (土) 18:04時点におけるWiki (トーク | 投稿記録)による版 (→‎SSLを使用した暗号化)
ナビゲーションに移動 検索に移動

概要



SSLを使用した暗号化

以下の例では、OpenSSLライブラリとQTCPSocketクラスを使用して、パケットを暗号化して送信している。

 #include <QTcpSocket>
 #include <QSslSocket>
 #include <QSslKey>
 #include <QSslCertificate>
 #include <QFile>
 
 // 暗号化
 void encryptPacket(QByteArray &packet)
 {
    // OpenSSLライブラリの初期化
    SSL_load_error_strings();
    SSL_library_init();
 
    // 公開鍵と秘密鍵を読み込む
    QSslKey privateKey("server.key", QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
    QSslCertificate publicKey("server.crt", QSsl::Pem);
 
    // QSslSocketオブジェクトの生成
    QSslSocket socket;
    socket.setPrivateKey(privateKey);
    socket.setLocalCertificate(publicKey);
    socket.connectToHostEncrypted("example.com", 443);
 
    // パケットの暗号化
    packet = socket.encrypt(packet);
 }
 
 int main()
 {
    // パケットの生成
    QByteArray packet = "Hello, world!";
 
    // パケットの暗号化
    encryptPacket(packet);
 
    // 暗号化されたパケットの送信
    QTcpSocket socket;
    socket.connectToHost("example.com", 1234);  // ホスト名とTCPポート番号の指定
    socket.write(packet);
 
    // 送信が完了するまで待機
    socket.waitForBytesWritten();
 
    return 0;
 }


以下の例では、暗号化されたパケットを送信するために、TCPソケットとパケットデータを引数として受け取り、OpenSSLライブラリを使用してSSLセッションを確立して、パケットを暗号化して送信する。
SSLセッションは、QSslSocketクラスを使用して確立される。

この時、事前に、サーバの証明書、クライアントの秘密鍵、サーバの公開鍵をファイルから読み込む必要がある。

 #include <QTcpSocket>
 #include <QSslSocket>
 #include <QSslKey>
 #include <QSslCertificate>
 #include <QFile>
 
 void sendEncryptedPacket(QTcpSocket *socket, const QByteArray &packet)
 {
    // OpenSSLライブラリの初期化
    SSL_load_error_strings();
    SSL_library_init();
 
    // SSLコンテキストを生成
    SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_client_method());
 
    // サーバの証明書を読み込む
    QFile certFile("server.crt");
    certFile.open(QIODevice::ReadOnly);
    QSslCertificate cert(certFile.readAll());
    certFile.close();
    SSL_CTX_use_certificate(ctx, cert.handle());
 
    // クライアントの秘密鍵を読み込む
    QFile keyFile("client.key");
    keyFile.open(QIODevice::ReadOnly);
    QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "my passphrase");
    keyFile.close();
    SSL_CTX_use_PrivateKey(ctx, key.handle());
 
    // サーバの公開鍵を読み込む
    QFile pubkeyFile("server.pub");
    pubkeyFile.open(QIODevice::ReadOnly);
    QSslCertificate pubkey(pubkeyFile.readAll());
    pubkeyFile.close();
    SSL_CTX_add_extra_chain_cert(ctx, pubkey.handle());
 
    // SSLセッションの確立
    QSslSocket sslSocket;
    sslSocket.setSocketDescriptor(socket->socketDescriptor());
    sslSocket.setProtocol(QSsl::TlsV1_2);
    sslSocket.setLocalCertificate(cert);
    sslSocket.setPrivateKey(key);
    sslSocket.addCaCertificate(pubkey);
    sslSocket.startClientEncryption();
 
    // パケットの暗号化
    QByteArray encryptedPacket = sslSocket.encrypt(packet);
 
    // 暗号化されたパケットの送信
    socket->write(encryptedPacket);
    socket->flush();
    socket->waitForBytesWritten();
 
    // SSLセッションの終了
    sslSocket.close();
 }