Java アプリケーションのセキュリティを確保するには? これが標準的な答えです | Dragon Lizard Technology

Text / Ziyi Lin、Cloud Native Confidential Computing SIG メンテナー

「Java プログラム メモリ内のパスワードを安全に保つにはどうすればよいですか?」

同様の問題を抱えていて、インターネット上で不完全だがどうしようもない答えを見つけた場合、それはあなたが Java プログラムのセキュリティ問題の利害関係者であることを意味します。

この質問に対する標準的な答えは、Java Confidential Computing Technology です。これは、Confidential Computing Technology を Java の世界に導入し、Java プログラムのセキュリティを大幅に改善します。これに基づいて、Dragon Lizard コミュニティの Cloud Native Confidential Computing SIG は、Java Confidential Computing の特定の実装技術である Teaclave Java TEE SDK (以降 Teaclave Java と呼ぶ) を立ち上げました。このテクノロジーには、次の重要な利点があります。

  • オール シナリオ セキュリティユーザーがコンフィデンシャル コンピューティング ハードウェア サポートを利用している場合、Teaclave Java は最高のセキュリティ レベルで Java トラステッド コンピューティングを実現できます; ユーザーが関連するハードウェアを持っていない場合、セキュリティ サンドボックス分離レベルでトラステッド コンピューティングに退化します。機密データとコンピューティング プロセスのセキュリティ。

  • 開発と構築が簡単SPI、ワンクリック構築に基づく純粋な Java プログラミング モデルは、Java Confidential Computing の開発と構築の敷居を底まで下げます。

Teaclave Java は、エンタープライズ レベルの内部シナリオで検証されており、Apache コミュニティでオープン ソース化されています。この技術に関する論文は、Dragon Lizard Community の Cloud Native Confidential Computing SIG の協力により、ソフトウェア工学のトップミーティングであるICSE 2023 (https://conf.researchr.org/home/icse-2023)で公開されました。上海交通大学および大連理工大学と共同研究を行い、この会議の ACM SIGSOFT Outstanding Paper Award を受賞しました。Dragon Lizard Community Cloud Native Confidential Computing SIG、上海交通大学、大連理工大学がこの栄誉を獲得したのは 2020 年以来のことです。

01  問題の本質

この問題の本質は、危険なランタイム環境で機密データを安全に使用する方法です。実行時にパスワードを復号化すると、図 1 の左半分に示すように、パスワードはプレーン テキストの形式でメモリ内、つまり Java ヒープ上に存在します。悪名高い 2021 年の log4j 脆弱性攻撃など、システムが攻撃された場合、Java ヒープの内容が盗まれる可能性があります。攻撃を受けなくても、パフォーマンス診断のためにヒープ ダンプを実行すると、機密情報が積極的に漏えいする可能性があります。そのため、パスワードなどの機密情報を一般的な運用環境にさらすことは、非常に危険です

(図 1 の単純な Java パスワード保護の概略図)

保護の 1 つの方法は、機密情報が公開される時間枠を短縮するために、平文のパスワードをメモリに保存する時間をできる限り短縮することです図 1 の右半分に示すように、パスワードが使用された後、パスワードは時間内にメモリから破棄され、以前よりも安全になります。パスワードはテキスト情報のため、文字列クラスjava.lang.Stringで保存されます。Java の String は不変型であり、作成後に内容を変更できないため、内容をリセットできる API はありません。パスワードを破棄するには、Java ヒープからパスワードの内容を消去する唯一の方法は、String クラス内の文字の内容を格納する配列の内容をリフレクションによってクリアすることです。パスワード文字列を直接 null に設定しても意味がなく、これは String 変数のポインタを null に設定するだけであり、Java ヒープ上のパスワード データには影響しません。もう 1 つの方法は、パスワードを String クラスではなく char 配列に格納することです。これにより、リフレクションを呼び出す必要がなくなり、破棄がより便利になります。もう 1 つの方法は、バイト配列を使用してパスワードを保存することです。これは、平文が人間が読める文字ではなく文字エンコーディングであるため、人々が理解するのがより困難になるためです。

これらは、今日インターネットで見つけることができる解決策であり、この記事ではそれらを「単純な」Java パスワード保護スキームと呼んでいますこれらのスキームは、Java ヒープ上の平文パスワードの寿命を縮めるだけで、平文パスワードを実際には保護しないためです。また、「タイムリー」という言葉には柔軟性があり、開発者はいつタイムリーかを正確に判断できない場合があります。

より典型的なケースは、有名な log4j の脆弱性の問題 ( https://nvd.nist.gov/vuln/detail/CVE-2021-44228 ) です。攻撃者は、log4j 2.14 の脆弱性を悪用して、悪意のあるクラス ファイルをサーバーにアップロードし、Java の動的クラス ローディング メカニズムを介して実行することで、Java ヒープに保存されているサーバーの秘密鍵を盗むことができます。秘密鍵を使用すると、サーバーとクライアント間のすべての通信コンテンツが攻撃者にとって平文になります。

上記の両方の例で、実行時に保護する必要があるパスワードとキーは、機密データです。実際のシナリオでは、保護の範囲は機密データに限定されず、コンピューティング プロセスにまで拡張される場合がありますたとえば、認証および認証シナリオでは、認証プロセスが信頼でき、攻撃者によって改ざんできないことを確認する必要があります。もう 1 つの例は、クラウド サービスのユーザーが独自のアルゴリズムをクラウドにデプロイする場合で、デプロイされた製品は暗号化して伝送とストレージのセキュリティを保護でき、クラウド ベンダーは外部からの攻撃に対する強固なセキュリティ保護を提供しますが、ユーザーは依然としてクラウド コンピューティングについて心配しています。製造元は、実行時にユーザーのコンピューティング プロセスをスパイし、自己盗用の可能性があるかどうかを調べます。

Java アプリケーションで機密性の高いデータと計算を保護することは、遠い要求ではなく、差し迫った実用的な重要性を持つ要求であることがわかりますクラウド コンピューティング プロバイダーにとって、機密データと計算がクラウド ベンダーには見えないことをユーザーに納得させるブラック ボックスには、大きな商業的価値もあります。

02  Java Confidential Computing の現状

機密データを実行時に保護することは新しいトピックではありませんが、20 年以上にわたって進化してきたテクノロジー、つまりコンフィデンシャル コンピューティングの一部です。コンフィデンシャル コンピューティングは、ハードウェア レベルのシステム分離を提供して、データ セキュリティとプログラム操作のセキュリティを確保するテクノロジです。コンフィデンシャル コンピューティングでは、実行環境をリッチ実行環境 (REE) と信頼できる実行環境 (Trusted Execution Environment、TEE) に分け、REE と TEE は互いに分離する必要があり、TEE はハードウェアによって暗号化されて、外の世界は内容を知ることができません。セキュリティ上重要なコンテンツは TEE で実行し、その他のコンテンツは REE で実行する必要があります。

このメカニズムは 1999 年に提案されましたが、初期のハードウェア暗号化テクノロジは機能が限られており、暗号化および復号化プログラムの実行をサポートする TPM (Trusted Platform Module) ハードウェアのみでした。2008 年、Arm は、TrustZone テクニカル ホワイト ペーパーをリリースして、Arm プラットフォームでの汎用コンフィデンシャル コンピューティング タスクをサポートしました。2015 年には、Intel も汎用アプリケーション暗号化をサポートする SGX (Software Guard Extension) チップを搭載したハードウェア デバイスを発売しました.2021 年には、SGX は、1T メモリをサポートし、より高いパフォーマンスを備えた SGX2 にアップグレードされます。

Confidential Computing の核となる概念は、攻撃を受ける危険性があるランタイム環境で、機密性の高いプログラムを実行するための安全な領域を提供し、機密性の高いデータとプログラムのセキュリティと信頼性を、機密コンピューティングのプロセス全体で実現することです。伝送、ストレージ、およびコンピューティング。現在、コンフィデンシャル コンピューティングには、プライバシー セキュリティ、ブロックチェーン、マルチパーティ コンピューティング、IoT およびエッジ デバイス、パーソナル コンピューティング デバイスなど、幅広いアプリケーションと幅広い展望があります。

Confidential Computing Technology は、Java プログラムのセキュリティの問題を解決するための標準的な答えのようですが、Confidential Computing Technology を Java アプリケーションに適用できますか?

Occlum - JVM とアプリケーションのモノリスを TEE に配置します

SGX、TrustZone などは、汎用コンフィデンシャル コンピューティングのハードウェア基盤を提供し、Intel や Microsoft などのオープン ソース ドライバーと SDK は、汎用コンフィデンシャル コンピューティングのソフトウェア基盤を提供します。これらのハードウェアとソフトウェアの基盤に基づいて、開発者は既にコンフィデンシャル コンピューティングをソフトウェア アプリケーションで使用できます。しかし、TEE で実行できるのはネイティブ プログラムのみであり、Java プログラムを TEE で直接実行することはできないため、Confidential Computing は Java アプリケーションには適していません。TEE で Java プログラムを実行するには、まず TEE で JVM を起動してから、JVM で Java プログラムを実行する必要がありますTEE 内で JVM を実行することは可能ですか? 答えはイエスです。それが Occlum です。その原理を図 2 に示します。

Occlum は、TEE の基盤となる SDK と JVM の間の LibOS のレイヤーであり、オペレーティング システムとして、TEE 内の通常の JVM の操作をサポートしますユーザーは、Occlum がサポートする JVM によって実行される TEE 内の機密コードを含む Java プログラム全体をデプロイします。図 2 の右半分はデプロイメント構造を示しています。黄色の APP は Java アプリケーション全体とそれに必要なサードパーティ ライブラリを表し、赤い円は信頼できるコードを表しています。アプリケーションは、REE のランチャー (通常は小さなコマンドライン ツール) によって起動されます。このソリューションには優れた互換性があり、ユーザーは基本的に、コンフィデンシャル コンピューティングのサポートを受けるために元のコードを変更する必要はありません。しかし、欠点も明らかです。TEE にコードが多すぎると、次の 2 つの問題が発生します。

1. セキュリティの低下TEE で実行する必要があるトラステッド プログラムはそれほど多くないかもしれませんが、このソリューションでは、すべての Java プログラム、サードパーティ ライブラリ、JVM、および LibOS を TEE に配置する必要があるため、TCB (Trusted Computing Base) が大きくなりすぎて、セキュリティが確保されません。理想。TCB は、信頼できるコードの量を参照して、セキュリティ分野でセキュリティを測定するための重要な指標です。TCB が大きいほど、セキュリティ リスクを伴う可能性のあるコードが多くなり、プログラムのセキュリティが低下するため、TCB が小さいほど優れています例として log4j 攻撃を取り上げますが、Occlum はまだそれに対する耐性がありません。log4j ライブラリと機密コードは異なる実行環境に分離されず、TEE にデプロイされるため、攻撃者によってアップロードされた悪意のあるクラス ファイルも TEE に配置され、秘密鍵は引き続きメモリからアクセスできます。 .

2. パフォーマンスの低下TEEのハードウェアは汎用的なハードウェアではなく、REEに比べて性能劣化があるため、アプリケーション全体をTEEに入れることはアプリケーション全体の性能劣化につながります。ただし、ユーザーの本来の要求は部分的な暗号化のみであり、部分的な暗号化によって引き起こされる全体的なパフォーマンスの低下は、Confidential Computing を適用するコストを増加させます。一般ユーザーは、セキュリティ上の理由からある程度のパフォーマンス低下を受け入れることができますが、過度の暗号化による追加のパフォーマンス低下を受け入れることは困難です。

(図2 Occlum原理の模式図)

要約すると、Occlum スキームにはシンプルで実装が容易であるという利点がありますが、セキュリティとパフォーマンスの面での欠点が実用化の主な障害となっています。

03  Teaclave Java TEE SDK – 信頼できるコードのみを TEE に入れる

JVM とすべてのアプリケーションを TEE でサポートするスキームは、TEE で実行されるコードが多くなりすぎて、セキュリティとパフォーマンスが低下するため、実践するのは困難です。信頼できるコードが TEE に組み込まれていますか? TEE で実行できるのはネイティブ コードのみであることを考えると、信頼できるコードを Java コードからネイティブ コードに直接コンパイルし、それを TEE に入れて実行することは可能ですか? 答えはイエスです。これがこの記事の主役である Teaclave Java TEE SDK (以下 Teaclave Java と呼びます) です。

Teaclave Java は、JVM チームが開発した Java Confidential Computing 開発フレームワークおよび構築ツール チェーンであり、Java Confidential Computing アプリケーションの開発と構築をワンストップで迅速に実現できます。ユーザーがコンフィデンシャル コンピューティングをサポートするハードウェア環境を持っていない場合でも、一歩下がって、Teaclave Java はセキュリティ サンドボックスの分離を実現し、機密データとプログラムのランタイム セキュリティを効果的に確保できます。

Teaclave Java の主な技術的特徴は次のとおりです。

1) モジュール分離とコンフィデンシャル コンピューティング サービス (図 3 参照)。

2) 簡潔で完全なコンフィデンシャル コンピューティング サービス ライフサイクル管理 API。

3) Java はシークレットを静的にコンパイルします。

4) 実装の詳細を隠し、すべての補助コードを自動的に生成します。

図 4 に示すように、これらのテクノロジーのサポートにより、Teaclave Java は、通常のモジュールから機密モジュールへの Java モジュール間のサービス呼び出しを、通常のモジュールから機密のネイティブ ライブラリへの関数呼び出しに変換できます。

モジュール分離、秘密計算サービス

Teaclave Java は、アプリケーション コードをHost、Enclave、および Commonの 3 つのモジュールに分割します。Host は一般的なセキュリティ非機密プログラムであり、Enclave はセキュリティ機密プログラムであり、Common は前者の 2 つで使用される共通コードです。このモジュール分割の方法は、開発者がコードのセキュリティの違いを認識できるようにするためであり、2 つ目は、構築中にさまざまなモジュールに対してさまざまなツール チェーンを使用しやすくするためです。

Host と Enclave は分離されており、Java の SPI (Service Provider Interface) メカニズムを介してのみ対話でき、直接呼び出すことはできません。Confidential Computing の実装は Enclave モジュールのサービスとしてパッケージ化され、そのインターフェイス宣言は Common モジュールで定義され、@EnclaveService アノテーションでマークされます。ホスト内のプログラムが特定のコンフィデンシャル コンピューティング タスクを使用する必要がある場合、最初にサービス インスタンスをロードしてから、対応する関数を呼び出すことができます。この構造の組織的関係を図 3 に示します。

(図 3 Teaclave Java の開発ビュー)

たとえば、Common のコード ブロック 1 に示されている Confidential Computing サービス インターフェイスを宣言できます。これは、API を提供し、暗号化されたパスワードが有効かどうかを認証するための関数を認証します。この関数は、ユーザーから渡された暗号化されたパスワードを受け取り、パスワードの認証結果を返します。

@EnclaveService
public interface AuthenticationService {
    /**
     * Given an encrypted input password, check if it is the correct password.
     * @param inputPwd the encrypted password to be authenticated
     * @return true if the given password is correct.
     */
    boolean authenticate(String inputPwd);
}

コード ブロック 1 は、Common モジュールのコンフィデンシャル コンピューティング サービス インターフェイス宣言の例を定義します。

AuthenticationService インターフェースの特定の実装は、コード ブロック 2 に示すように、Enclave モジュールの AuthenticationServiceImpl クラスで定義されます。このクラスの認証関数は、まず秘密鍵を使用して入力された暗号化文字列を復号化して平文の結果を取得し、メモリに格納されている正しいパスワードと比較して、整合性をチェックした結果を返します。このクラスに格納されている正しいパスワード値と秘密鍵はすべて、機密性の高いデータであり、認証機能の実装も機密性の高い操作です。これらはすべて TEE で実行され、外部使用用のブラック ボックスとして利用できます。外部からは暗号化された入力データと返された判定結果のみが見え、実際の運用過程やデータは覗き見ることができません。

public class AuthenticationServiceImpl implements AuthenticationService {

    private String pwd = "somePwd"; // assume it's got at runtime.

    @Override
    public boolean authenticate(String inputPwd) {
        String decryptedInputPwd = decrypt(inputPwd);
        return pwd.equals(decryptedInputPwd);
    }

    private static String decrypt(String inputPwd) {
        return inputPwd; // assume it's decrypted with private key
    }
}

コード ブロック 2 は、Enclave モジュールでのコンフィデンシャル コンピューティング サービス インターフェイスの実装例を定義します。

コンフィデンシャル コンピューティング サービスを使用する Host モジュールのコード例をコード ブロック 3 に示します。ここから、コンフィデンシャル コンピューティング サービスの AuthenticationService インターフェイスの使用は、通常の SPI インターフェイスと同じであり、まだサービスをロードしていることがわかります。関数を呼び出し、結果に応じてさまざまなアクションを実行するなどのプロセス。わずかな違いは、コンフィデンシャル コンピューティング環境 Enclave のインスタンスを最初に作成する必要があり、次にコンフィデンシャル コンピューティング サービス インスタンスがそこから読み込まれ、それによってコンフィデンシャル コンピューティング サービス インスタンスと環境インスタンスがバインドされ、最後に環境が破棄されることです。これらのコンフィデンシャル コンピューティング環境のライフサイクル管理用の API は Teaclave Java によって提供されます。コード ブロック 3 からわかるように、Host モジュールでは、パスワードと秘密鍵が何であるかを知る必要も、認証プロセスを理解する必要もありませんが、認証機能をブラック ボックス サービスとして呼び出す必要があります。

public class Main {
    public static void main(String[] args) throws Exception {
        Enclave enclave = EnclaveFactory.create();
        Iterator<AuthenticationService> services = enclave.load(AuthenticationService.class);
        String pwd = "encryptedPwd"; // assume this is an encrypted password
        while (services.hasNext()) {
            AuthenticationService authenticationService = services.next();
            if (authenticationService.authenticate(pwd)) {
                System.out.println("Passed");
            } else {
                System.out.println("Rejected");
            }
        }
        enclave.destroy();
    }
}

コード ブロック 3 ホスト モジュールから Confidential Computing Service を使用する例

上記のコードの 3 つの部分は、完全な Java Confidential Computing アプリケーションを構成します。開発の観点からは、通常の SPI サービスによって呼び出されるアプリケーションを作成するのと基本的に同じように見えます.ビジネス ロジックの開発に集中するだけでよく、Confidential Computing の基本的な内容を学ぶ必要はありません. したがって、Teaclave Java は、Java Confidential Computing の開発しきい値をゼロに引き下げます。

Confidential Computing アプリケーションの構築

Teaclave Java は、上記のプログラミング モデルをサポートする構築ツール チェーンの完全なセットを提供し、ユーザーはいくつかの単純な maven コマンドを入力するだけで、すべての構築タスクを完了することができます。構築ツール チェーンは、非機密コードと機密コードを、SGX に展開できる Java バイトコード製品とネイティブ ライブラリにコンパイルし、機密コンピューティング サービス呼び出しを完了するために必要なすべての補助コードを自動的に生成します。

図 4 は、主に次の 3 つの側面を含む Teaclave Java のビルド・デプロイメント・ビューを示しています。

1) ホストおよび共通モジュールは、共通の Java バイトコードにコンパイルされ、共通の環境で展開および実行されます。

2) Enclave とそれが使用する共通モジュールの内容は、ネイティブの機密ライブラリ ファイルにコンパイルされ、実行のために SGX ハードウェアに展開されます。

3) Java バイトコードからネイティブ コードに直接呼び出すことはできませんが、次のようないくつかの適応および変換作業が必要です。

  • サービス プロキシ: Java の動的プロキシ メカニズムを介して、ホスト モジュール内のコンフィデンシャル コンピューティング サービス呼び出しが実際のネイティブ関数に委譲され、コンテキストの同期、サービス パラメータのシリアル化と逆シリアル化、および戻り値が完了します。

  • JNI 層: Java 側のネイティブ関数宣言、ネイティブ側の JNI 関数宣言、機密ライブラリ関数の呼び出しなどの補助コード。

(図 4 Teaclave Java デプロイメント・ビュー)

これらの適応変換によって呼び出されるコードは、構築中に自動的に生成され、通常の環境と SGX にそれぞれ展開されます (図 4 で青色でマークされています)。

ビルド プロセスの重要なステップは、Java コードの機密部分をネイティブ コードにコンパイルする Java 静的コンパイルです。

Java 静的コンパイル

Java プログラムは本来 JVM 上で実行する必要がありますが、Java 静的コンパイル テクノロジを使用すると、Java プログラム (JDK ライブラリの依存関係およびサードパーティ ライブラリの依存関係を含む) を必要なランタイム サポート コードと共にネイティブ コードにコンパイルし、直接実行できます。このようにして、JVM を使用しない Java プログラムの軽量な実行が実現されます。

Teaclave Java は、最も成熟した Java 静的コンパイル技術である Oracle 主導のオープン ソース プロジェクト GraalVM for Java static compilation を使用しますGraalVM は最初に Java プログラムの到達可能性を分析し、プログラム エントリから実行可能なすべてのコード範囲を見つけてから、これらの到達可能なコードのみをコンパイルしてネイティブ アーティファクト (ネイティブ イメージと呼ばれます) を取得します。プログラム エントリは、実行可能プログラムのメイン関数であり、ライブラリ ファイルの公開されたパブリック API です。Teaclave Java シナリオに固有のエントリ ポイントは、開発者によって定義されたコンフィデンシャル コンピューティング サービス関数、つまり、Enclave モジュールで定義されたコンフィデンシャル コンピューティング サービス インターフェイスの実装関数です。これらのインターフェースの実装は、Common モジュールのコード、一部の JDK ライブラリ、およびその他の Java サードパーティ ライブラリの 3 つの依存関係を使用しますが、すべてのコードではなく、これらの依存関係のコードの一部のみが使用されます。GraalVM は実際に使用されているコードを解析し、コンフィデンシャル コンピューティング サービスの実装コードと GraalVM が提供するランタイム サポート (Substrate VM と呼ばれます) と共にネイティブ イメージにコンパイルします。ただし、GraalVM は一般的なシナリオとハードウェア プラットフォームを対象としているため、Teaclave Java はさらに、SGX ハードウェア プラットフォームの適応と機密コンピューティング要件の最適化を提供します。ネイティブ イメージをコンパイルすると、いくつかの特別なプロパティがあることがわかります。

  • TCB ドロップ. GraalVM は Confidential Computing Service ポータルから到達可能なコードのみをコンパイルするため、LibOS、JVM、および Java アプリケーションをすべて TEE に配置する Occlum のソリューションと比較して、TCB は大幅に削減されます。

  • セキュリティの向上ネイティブ イメージには、実行時に独自のネイティブ メモリ ヒープがあり、これは Java ヒープから分離されており、Java アプリケーションからアクセスするのが困難です (Java は Unsafe インターフェイスを介してネイティブ メモリにアクセスできますが、はるかに困難です)。さらに、Java の静的コンパイルは Java の動的特性を取り除き、コンパイル時に明示的に構成されたリフレクションと動的クラス ローディングのみが有効になり、実行時のその他の動的動作は無効になります。Log4j の脆弱性攻撃は、ネイティブ イメージ自体では無効です。したがって、ネイティブ イメージはセキュリティ サンドボックスと見なすことができ、SGX ハードウェア環境がなくても、ネイティブ イメージは Java プログラムと比較してセキュリティを向上させます。SGX にデプロイされた後、TEE セキュリティに対する Java の動的特性の脅威が排除されるため、TEE のセキュリティはより高くなります。

  • パフォーマンスの向上GraalVM の Java 静的コンパイルは、コードのコンパイル最適化がかなり進んでおり、実行時のパフォーマンスはおおむね JVM の C1 最適化レベルに達することができます.さらに、JVM を起動する必要がなく、クラスのロード プロセスがなく、解釈の実行もありません。 、リソースのJIT消費がないなど、Javaプログラムと比較して、短いタスクを実行する場合のパフォーマンスが桁違いに向上し、メモリも大幅に削減されます。

これらのプロパティは、機密プログラムのセキュリティを効果的に改善し、Teaclave Java の実用性を高めることができます。

04  Teaclave Java テクノロジー評価

上記は Teaclave Java が提供する Java Confidential Computing プログラミング モデルや採用されている構築方法などの技術的な問題を紹介していますが、最終的な実装効果はどのようなものですか? このホワイト ペーパーでは、log4j 脆弱性攻撃を例として、Teaclave Java の機能の有効性を分析します。

TCB の改善と実行時のパフォーマンス分析に関して、表 1 に示すように 10 個のテストを用意しました。最初の 4 つの "app-" プレフィックスは、自分で作成した単純なアプリケーションです. これらを機密プログラムとして扱い、それらのメイン エントリを通常のプログラムとして使用します. 「ct-」で始まる最後の 6 つのユース ケースでは、有名なオープン ソース暗号化フレームワーク BouncyCastle (https://www.bouncycastle.org/java.html)の単体テストを使用します。これらのテストを呼び出す単一のエントリを提供します。テストエントリを通常のプログラムとして、単体テストとして機密プログラムとして使用します。

テストケース メインの 3 パーティ ライブラリに依存する 説明
アプリ印刷 \ メッセージ文字列を出力する
アプリダイジェスト BouncyCastle-full BouncyCastle を呼び出してハッシュ値を計算する
app-rsa BouncyCastle-full RSA 暗号化のために BouncyCastle を呼び出す
アプリ-sqlparser ドルイド Druid による SQL 解析
ct-asn1 BouncyCastle-core BouncyCastle-core の asn1 サブモジュール テスト
ct-i18n BouncyCastle-core BouncyCastle-core の i18n サブモジュール テスト
ct ユーティリティ BouncyCastle-core BouncyCastle-core の util サブモジュール テスト
ct-数学 BouncyCastle-core BouncyCastle-core の数学サブモジュール テスト
ct-pqc BouncyCastle-core BouncyCastle-core の pqc サブモジュール テスト
ct-暗号 BouncyCastle-core BouncyCastle-core の Crypto サブモジュール テスト

(表 1 / テスト ケースの説明)

Java のコンフィデンシャル コンピューティング フレームワークは、比較のために OcclumJ と Teaclave Java を使用します。OcclumJ は、弊社が実装した Occlum と Teaclave Java 間の機密計算モデルです. Teaclave Java のモジュール化と機密計算サービス モデルを採用していますが、Java を静的にコンパイルするのではなく、TEE で Occlum モードで実行されます. Confidential Computing Services.

機能的有効性評価

図 5 は、log4j 脆弱性攻撃の原理 (サブ図 a) と、log4j 脆弱性攻撃を防止する Teaclave Java の原理 (サブ図 b) を示しています。通常の Java アプリケーション サービスの場合、クライアントとのやり取りは 3 つの手順で行われます。

1) クライアントはサーバーから公開鍵を取得します。

2) クライアントは公開鍵でメッセージを暗号化し、暗号文をサーバーに送信します。

3) サーバーはランタイム メモリから秘密鍵を取り出してメッセージを復号化し、メッセージの内容を処理します。サーバーがログに log4j-2.14.x バージョンを使用すると仮定すると、この脆弱性により、攻撃者は log4j を誘導して、指定された悪意のあるクラス ファイルをリモート サーバーからダウンロードさせ (図 5-a の手順 4、5、6)、次にロードすることができます。悪意のあるクラスは、Java ヒープ メモリから秘密鍵を取得し (ステップ 7)、それを攻撃者に渡します。

サーバーの秘密鍵を使用すると、サーバーとクライアント間のすべての通信が攻撃者にはプレーンテキストとして表示されます。

a. log4j 脆弱性攻撃の図

b. コンフィデンシャル コンピューティングによる log4j の脆弱性攻撃に対する耐性

(図 5 / Log4j 脆弱性攻撃からアプリケーションを保護する Java Confidential Computing の概略図)

図 5-b は、Teaclave Java がアプリケーション サーバーを log4j 脆弱性攻撃から保護する方法を示しています。Teaclave Java はアプリケーションの共通コードを REE に置き、セキュリティに配慮した復号化と秘密鍵を TEE に置きます. クライアントから送信された暗号化されたメッセージは、REE のプロキシ サービスによって TEE に転送され、復号化されます. このとき、攻撃者が log4j 攻撃を開始すると、Log4j は REE に配置されているため、悪意のあるコードは REE でのみ実行できますが、TEE メモリ内の秘密鍵を取得できず、攻撃は失敗します。機密コードがロギングにも log4j を使用し、log4j が TEE で実行されるとどうなりますか? この時点で、log4j は攻撃者の悪意のあるコードを TEE にダウンロードしましたが、Teaclave Java は Java 静的コンパイル技術を使用しているため、悪意のあるコードはコンパイル時に不明であり、ネイティブ イメージにコンパイルされません。Java の静的コンパイル技術は、ネイティブ イメージに存在しないコードの動的な読み込みと実行をサポートしていないため、悪意のあるクラスが TEE にダウンロードされても実行されません。したがって、このシナリオでは、Teaclave Java がサポートするコンフィデンシャル コンピューティングは依然として安全です。しかし、Occlum ソリューションを採用した場合、TEE に JVM があるため、悪意のあるコードを動的にロードして実行することができ、攻撃が成功します。

TEE を暗号化する SGX ハードウェアがない場合、ネイティブ イメージは依然としてネイティブ サンドボックスのままであり、悪意のある Java コードはネイティブ メモリからセキュリティ上重要なコンテンツを簡単に取得できません。

TCB 評価

Teaclave Java は LibOS と JVM を必要としなくなったため、機密コード部分もオンデマンドでコンパイルおよびデプロイされます。OcclumJ方式はサブモジュールモデルを採用していますが、静的解析は行っていないためモジュールレベルでコードを分割するだけで、Occlumの分割が全くない場合に比べれば改善されていますが、Teaclaveと比べるとまだかなりの差があります。 Javaの関数レベルの分割. . 図 6 は、TEE に入れられた OcclumJ と Teaclave の Java バイナリ ビルドのサイズの比較を示しています。青色のバーが OcclumJ の結果、オレンジ色のバーが Teaclave Java の結果、図中の Lejacon が論文中の Teaclave Java のコード名です。

(図 6 Occlum と Teaclave Java ソリューションの TCB 比較。Lejacon は、論文での Teaclave Java のコード名です)

図 6 の比較データからわかるように、Teaclave Java のコンパイル済み TCB サイズは、Occlum の約 1/20 から 1/10 にすぎませんコンパイル時のネイティブ コードの拡張を考慮すると、両者の実際の関数数の差はより大きくなるため、Teclave Java の TCB は、セキュリティが高い Occlum よりも桁違いに低くなります。

実行時のパフォーマンス評価

ネイティブ イメージはネイティブ コードの形式で直接実行されるため、JVM の起動、クラスのロード、解釈、および実行の手順を含む Java プログラムのコールド スタートアップ プロセスが省略されるため、起動速度が非常に高速になります。実行する機密コードが少ない場合は、すぐに実行されます。ただし、ネイティブ イメージのコード コンパイルの品質は JVM の C2 ほど良くないため、プログラムの実行時間が十分に長く、Java コードが JIT によって完全にコンパイルされると、ネイティブ イメージの実行時パフォーマンスが近くなります。そして時がたつにつれてJavaプログラムに近づき、そして超えていきました。そのため、小規模なアプリケーションでは Teaclave Java のパフォーマンスは OcclumJ よりもはるかに優れていますが、実行時間の長いアプリケーションではその利点が減少します。

図 7 は、この機能を示しています。図中の青い線は OcclumJ モデルを使用した機密コード部分の実行時間、黄色の線は Teaclave Java モデルを使用した実行時間、緑の線は通常の環境で通常の JVM で直接実行した時間です。 . TEE でのプログラムの実行時間は、通常の環境よりも長くなります。これは主に、機密環境の作成、機密メモリの割り当て、およびその他のオーバーヘッドが増加するためです。これらをまとめて機密環境のオーバーヘッドと呼びます。 . 黄色のラインは実行時間の短いシーンで緑色のラインに近いパフォーマンスを維持しており、Java プログラムのコールド スタートアップのオーバーヘッドがネイティブ イメージの機密環境のオーバーヘッドをほぼ相殺できることを示しています。プログラムの実行時間が長い場合、コールド スタートのオーバーヘッドは希薄になりますが、シークレット環境のオーバーヘッドは TEE のメモリ使用量に比例するため、最後の 3 つのテスト ケースでは黄色の線が緑色の線よりも急勾配になっています。

図 8 は、OcclumJ と Teaclave Java のランタイム メモリ使用量の比較を示しています。OcclumJ のメモリ消費量には、LibOS、JVM、およびアプリケーションの 3 つの部分が含まれますが、Teclave Java モデルのメモリ消費量は、アプリケーションとネイティブ イメージの軽量ランタイムのみです。より単純化された構造により、Teaclave Java モードでの機密コンピューティングのメモリー消費が少なくなります。

(図 7 OcclumJ と Teaclave Java のランタイム パフォーマンス比較チャート。Lejacon は、論文中の Teaclave Java のコード名です)

(図 8 / OcclumJ と Teaclave Java のランタイム メモリ消費量の比較。Lejacon は論文中の TeaclumJava のコード名です)

05  まとめ

Teaclave Java は、使いやすく、効果的で、優れたパフォーマンスを備えた Java Confidential Computing ソリューションであり、ユーザーが Java アプリケーションでセキュリティに敏感なコンテンツとコンピューティングを保護する問題を完全に解決するのに役立ちます。Teaclave Java にはハードウェア耐性があります. SGX ハードウェア環境を装備すると, Java ユーザーは他のネイティブ言語ユーザーと同様に機密コンピューティングによってもたらされる最高レベルの実行時セキュリティ保護を享受できます.セキュリティサンドボックス機密コードのメモリ分離を実装し、直接回避することができます.セキュリティ上重要なコンテンツの公開。Teaclave Java は、Java アプリケーションの機密データとコンピューティング セキュリティを保護するための標準的な答えであると言えます。

オラクルは GraalVM の Java 静的コンパイル技術を OpenJDK に提供しており、これは JDK 21 で OpenJDK バックボーンに統合される予定です。したがって、Teaclave Java ソリューションは、将来的に JDK からネイティブ サポートを取得できるようになります。Teaclave Java のコンフィデンシャル コンピューティング モデルをネイティブ Java コンフィデンシャル コンピューティング ソリューションにアップグレードすることを期待して、Java コミュニティにコンフィデンシャル コンピューティング仕様を追加するためのドキュメントも提出する予定です。

このテクノロジーによって公開された論文は、Xinyuan Miao、Ziyi Lin、Shaojun Wang、Lei Yu、Sanhong Li、Zihan Wang、Pengbo Nie、Yuting Chen、Beijun Shen、He Jiang です。 SGX .ICSE 2023。

論文リンク:

https://ddst.sjtu.edu.cn/Management/Upload/[ニュース]a845acae286b470bb55013c1b5e425e2/20232101456536725sSV.pdf

Teaclave Java プロジェクトのソース コードは Apache コミュニティに提供され、Confidential Computing フレームワークの Teaclave プロジェクトに参加し、現在はオープン ソース インキュベーションの段階にあります。

プロジェクトリンク: https://github.com/apache/incubator-teaclave-java-tee-sdk

Dragon Lizard Community Cloud Native Confidential Computing SIG のホームページ:

https://openanolis.cn/sig/coco

- 以上 -

おすすめ

転載: blog.csdn.net/weixin_60347558/article/details/130017368