sgcWebSockets のネイティブ Android TLS: OpenSSL のデプロイ不要

· コンポーネント

Delphi や C++Builder でセキュアな Android アプリを出荷するには、これまで常に余計な手間が 1 つ必要でした。実行時に OpenSSL を利用できるよう、libssl.solibcrypto.so を APK に同梱することです。sgcWebSockets はこの手間をなくします。新しいネイティブ TLS バックエンド iohAndroidTLS は暗号化を Android 自身に委ねるため、デプロイすべき OpenSSL ライブラリなしで TLS 接続できます。これは Enterprise エディションで利用できます。

内部では、このバックエンドが JNI を介してプラットフォーム自身の javax.net.ssl.SSLEngine を駆動します。ハンドシェイク、レコードの暗号化、証明書の検証はオペレーティングシステムが行います。sgcWebSockets は平文を入力して暗号文を受け取るだけであり、つまり TLS スタック全体は Google が OS とともに出荷しパッチを当てているものです。

切り替えは 1 行

TLS バックエンドは TLSOptions.IOHandler で選択します。Android のネイティブ TLS を使うには、これを iohAndroidTLS に設定します。ネットワークコードのそれ以外の部分は変わりません。

uses
  sgcWebSocket, sgcWebSocket_Types;

WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAndroidTLS;
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;

他のプラットフォームでは、それぞれに合ったバックエンドを使い続けられます。iohOpenSSL はどこでも動作し、iohSChannel は Windows でデプロイ不要のネイティブな選択肢です。小さな条件分岐により、単一のクライアントコンポーネントをすべてのターゲットで正しく保てます。

WSClient.TLS := True;
{$IFDEF ANDROID}
WSClient.TLSOptions.IOHandler := iohAndroidTLS;   // native, no OpenSSL .so
{$ELSE}
  {$IFDEF MSWINDOWS}
WSClient.TLSOptions.IOHandler := iohSChannel;     // native on Windows
  {$ELSE}
WSClient.TLSOptions.IOHandler := iohOpenSSL;      // OpenSSL elsewhere
  {$ENDIF}
{$ENDIF}
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;

APK に OpenSSL は不要

これが目玉の利点です。ネイティブバックエンドを使うと、APK には libssl.solibcrypto.so も含まれません。パッケージは小さくなり、OpenSSL のバージョンを追いかけたり、セキュリティ勧告に合わせて再ビルドしたり、ライブラリのビルドをデバイスに合わせたりすることは二度とありません。TLS の実装はデバイス上に存在し Android によって保守されるため、セキュリティ修正はリリースサイクルではなくシステムアップデートを通じて届きます。

これは一連のデプロイ問題も取り除きます。「ライブラリが見つからない」も、同梱した .so とデバイス間のアーキテクチャの不一致も、監査すべき暗号の 2 つ目のコピーもありません。プロパティを 1 つ設定して出荷するだけです。

機能を削った版ではなく、完全な TLS クライアント

このネイティブバックエンドは完全なクライアントです。Android のシステムトラストストアに対してサーバーを検証し、ホスト名の検証を行うため、公的な認証局への接続は追加の設定なしで動作します。TLS 1.3 をネゴシエートし、Android 10 (API 29) 以降では ALPN に対応しているため、ハンドシェイク中に http/1.1 などのアプリケーションプロトコルをアドバタイズできます。

他のすべてのバックエンドと同じ TLSOptions API の背後に位置するため、おなじみのプロパティはそのまま機能します。VerifyCertificate はピア検証のオン・オフを切り替え、RootCertFile はプライベートな認証局を信頼し、CertFilePassword はクライアント証明書を提示し、ALPNProtocols はネゴシエートするプロトコルを列挙します。

WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAndroidTLS;
WSClient.TLSOptions.VerifyCertificate := True;
WSClient.TLSOptions.ALPNProtocols.Add('http/1.1');  // Android 10 (API 29)+
WSClient.Host := 'your.server.com';
WSClient.Port := 443;
WSClient.Active := True;

すでにお使いのコンポーネントで動作します

このバックエンドは共有の TLSOptions に組み込まれているため、WebSocket クライアントに限定されません。TCP クライアントや HTTP/2 クライアント、そして TLSOptions を公開する他のコンポーネントも、同じ方法でこれを選択します。コードがすでに TLSOptions を設定しているなら、ネイティブ Android TLS の追加は代入 1 つで済み、接続の開始、送信、受信の方法は何も変わりません。

Apple でも同じ考え方

iOS や macOS もターゲットにしているなら、対になる iohAppleTLS バックエンドがそこで同じ役割を果たします。Apple 自身の TLS を使うのでデプロイすべき OpenSSL の .dylib はなく、Network.framework を通じて TLS 1.3 に到達します。パターンは同一で、プラットフォームごとにネイティブハンドラを選ぶだけです。詳細は Native Apple TLS のページでご覧いただけます。

利用可能なエディション

ネイティブ Android TLS (iohAndroidTLS) は sgcWebSockets の Enterprise エディションで出荷されます。4 つの TLS バックエンド、すなわちすべてのプラットフォームでの OpenSSL、Windows での SChannel、そしてネイティブの Android および Apple ハンドラの完全な内訳については、SSL / TLS セクションNative Android TLS のページをご覧ください。

sgcWebSockets のダウンロードページからダウンロードするか、GetIt または登録済みのアカウントを通じて入手してください。

ご質問、フィードバック、または Android アプリを OpenSSL から移行する際のサポートが必要ですか? お問い合わせください。コードを書いた本人から返信が届きます。