OpenSSLのDLLなしのDelphi TLS 1.3

· コンポーネント
OpenSSLのDLLなしのDelphi TLS 1.3

TLSを出荷したことのあるすべてのDelphi開発者は、あの手順を知っています。このマシンにはどのバージョンのOpenSSLが入っているか。なぜ顧客のサーバーには1.1があり、ビルドマシンには3.0があるのか。実行ファイルの横にどの二つのDLLを置くべきか、そしてウイルス対策ソフトがそのうちの一つを削除したらどうなるか。sgcWebSockets 2026.10は、そこから抜け出す道を用意しました。ライブラリの内部に組み込まれた、Object Pascalで書かれたTLS 1.3およびTLS 1.2エンジンで、いかなる種類のDLLも必要としません。

これはラッパーではなく、本物の実装です。ハンドシェイク、レコード層、キースケジュール、証明書検証はすべてPascalで書かれています。クライアントもサーバーも、何もインストールせずにTLSで通信します。

たった一つのプロパティ

oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'wss://www.esegece.com:2053';
oClient.TLSOptions.IOHandler := iohNativeTLS;
oClient.Active := True;

サーバーでは、SSLOptionsにある同じスイッチです。

oServer.SSLOptions.IOHandler := iohNativeTLS;
oServer.SSLOptions.CertFile := 'server.pem';
oServer.SSLOptions.KeyFile := 'server.key';
oServer.SSL := True;

ALPN、S N I、クライアント証明書はいずれも用意されており、Indyのhandlerでも、I O C PおよびE P O L Lサーバーでも利用できます。それ以外にあなたのコードで変わるものはありません。

TLS 1.3およびTLS 1.2

このエンジンはクライアントとしてもサーバーとしても、TLS 1.3とTLS 1.2の両方で通信し、双方が対応していれば常にTLS 1.3が選ばれます。TLSOptions.Version、サーバーではSSLOptions.Versionが許可する最低バージョンで、残りは暗号スイートのリストが決めます。

// TLS 1.3 and TLS 1.2, tls1_2 is the lowest version allowed
oClient.TLSOptions.Version := tls1_2;

// TLS 1.3 only
oClient.TLSOptions.Version := tls1_3;

// TLS 1.2 only: name TLS 1.2 suites and no TLS 1.3 suite
oClient.TLSOptions.Version := tls1_2;
oClient.TLSOptions.NativeTLS_Options.CipherSuites :=
  'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256';

デフォルトでTLS 1.2が提供するのは、ECDHEとAES-GCM、ChaCha20-Poly1305による前方秘匿性のあるスイートだけです。AES-CBCのスイートとRSA鍵交換は、古いピアのために用意されていますが、名前を指定したときだけ使われます。TLS 1.2は、既知の攻撃の原因となった部分を取り除いて実装されています。拡張マスターシークレット(RFC 7627)、再ネゴシエーションなし、SHA-1署名なし、双方向のRFC 8446ダウングレード保護、そして定数時間のCBCチェックです。ハイブリッドなポスト量子グループはTLS 1.3にしか存在しないため、TLS 1.2の接続ではX25519、secp256r1、secp384r1のいずれかを使用します。

マシンがすでに信頼しているものを信頼する

TLSクライアントは、その信頼アンカーの分だけしか優れていません。そして経年劣化していくcacert.pemを配布することは、それ自体が保守上の問題です。このエンジンは、オペレーティングシステムがすでに信頼しているルート証明書を使うことができます。

oClient.TLSOptions.NativeTLS_Options.UseSystemRoots := True;

Windowsでは、それらはROOTシステムストアから来ます。LinuxとAndroidでは、通常の場所の中から最初に見つかった証明書バンドルから来ます。これはデフォルトで無効になっており、そのおかげで信頼アンカーはRootCertFileが示すものだけに保たれます。

明日のために、今日のポスト量子

今日あなたのTLSセッションを破ることができない攻撃者でも、それを記録して保存しておくことはできます。興味深い問いは、量子コンピューターが今すでに存在するかどうかではなく、あなたの通信がどれだけ長く機密であり続けるかです。だからこそTLSはハイブリッド鍵交換へと移行しつつあります。この方式では、二つの半分のうちどちらか一方さえ持ちこたえれば、共有される秘密は安全です。

このエンジンはRFC 10024のハイブリッドグループをネゴシエートし、デフォルトのグループリストはすでにハイブリッドのものから始まります。

oClient.TLSOptions.NativeTLS_Options.Groups :=
  'X25519MLKEM768:SecP256r1MLKEM768:X25519';

三つのハイブリッドはX25519MLKEM768、SecP256r1MLKEM768、SecP384r1MLKEM1024です。どちらのリストもコロンで区切られたOpenSSLスタイルの名前を取り、空の値はエンジンのデフォルトを維持します。

その裏にある暗号技術

同じリリースでは、ポスト量子プリミティブそのものがsgcCryptoパックにObject Pascalで、外部ライブラリなしに追加されました。

これらは、単なる主張としてではなくテストセットとしてライブラリに同梱されているNISTの既知応答ベクトルに対して検証されています。

頼まなくても手に入る耐タンパー性強化

同じ改修で、古典的な側もタイミング攻撃に対して強化されました。RSA秘密鍵の演算はブラインディングと結果検証付きの定数時間べき乗を使い、楕円曲線のスカラー倍算とEd25519署名は定数時間で実行され、AESとGHASHはもう秘密のバイトでテーブルを参照することがありません。秘密鍵はインポート時にチェックされるため、その証明書に属さない鍵は、誰も検証できない署名を生成する代わりに拒否されます。また、ASN.1エンコーディングが最小のDERでない署名は、受け入れられるのではなく拒否されるようになりました。

どちらをいつ使うか

OpenSSLとSChannelはなくなるわけではなく、多くのアプリケーションにとって今も正しい答えであり続けます。TLS 1.2より古いものと通信する必要がある場合や、セッション再開が必要な場合はOpenSSLを、顧客のポリシー上Windowsが暗号を所有すべきならSChannelを使ってください。ネイティブエンジンは、デプロイそのものが問題になる場合のためのものです。単一の実行ファイル、横にDLLは一切なし、WindowsでもLinuxでも同じ振る舞い、そしてプラットフォームが追いつくのを待たずに使えるポスト量子鍵交換です。

アップグレード

このエンジンはsgcCryptoパックの一部であり、コンポーネントごとに選択されるため、IOHandlerを設定するまでは何も変わりません。暗号関連のunitを含まないビルドは、ハンドシェイクで不可解に失敗する代わりに、明確なメッセージを発生させます。

次に読む

動画で見る

この内容についての短い動画がeSeGeCeチャンネルにあります。

質問、フィードバック、移行のお手伝いが必要ですか?お問い合わせください — コードを書いた本人たちから返信が届きます。