ホームページ > 記事 > ウェブフロントエンド > Javascript を使用して暗号化および復号化する
Opal Web サイトを作成するときに私たちが直面した課題は、ブラウザーで暗号化および復号化する信頼できる方法を見つけることでした。
この記事では、ブラウザ側の暗号化が直面する課題について説明し、最近の技術の進歩によって提供されるソリューションを特定します。
Web アプリケーションの暗号化のための 3 つのオプション
すべてのブラウザでサポートされている言語は JavaScript のみです。 Opal のような Web アプリケーションは、最新のブラウザで実行できるように JavaScript で作成されています。これらのアプリケーションが暗号化関数を使用する場合は、JavaScript が暗号化関数にアクセスできる必要があります。
現在、暗号化関数をブラウザの JavaScript に公開するオプションは 3 つだけです:
1. プラグイン暗号化を使用する
プラグインは、ブラウザ内で実行され、JavaScript によって呼び出すことができるコンパイルされたコードを指します。
たとえば、Java や Flash に存在する暗号化ライブラリ。このアプローチは通常、非常にパフォーマンスが高いですが、ユーザーはブラウザ プラグインをインストールする必要があり、これは人々が (公共のコンピューターを使用している場合には) 実行したくない、または実行できないことです。
もう 1 つのオプションは、Chrome ブラウザの NaCl クライアント (ネイティブ クライアント) プログラムを使用することです。これにより、C または C++ からコンパイルされたマシン コードを実行できます。繰り返しますが、このアプローチは非常にパフォーマンスが高いですが、NaCl クライアント プログラムは Chrome ブラウザーでのみ使用できます。
これらのプラグインと NaCl クライアント プログラムには速度の点で利点がありますが、ユーザーは特別なプラグインを使用するか、特定のブラウザを使用する必要があるため、このアプローチの移植性はあまり良くありません。
2. Web 暗号化 API を使用する
今後の Web 暗号化 API は、JavaScript にネイティブの基本暗号化インターフェイスを提供し、Web アプリケーションの暗号化と復号化を高速化できるようにします。ただし、このインターフェースはまだドラフト段階にあり、主流のブラウザーがこのテクノロジーを採用するまでには長い時間がかかるでしょう。現在、ほとんどのブラウザで使用できる関数は crypto.getRandomValues() 関数のみです。
これは、Web 暗号化 API が広く使用されるまで、実用的なブラウザ側の暗号化ソリューションではありません。
3. JavaScript を直接使用して暗号化する
このソリューションの利点は、移植性の高さです。すべてのブラウザーは JavaScript を実行できます。つまり、すべてのブラウザーは JavaScript で記述された暗号化ライブラリを呼び出すことができます。
JavaScript の暗号化には、セキュリティと速度という 2 つの主な欠点があります。これら 2 つの欠点について順番に説明します。
JavaScript 暗号化は安全になる可能性があります
ある記事では、「JavaScript 暗号化は有害である」と主張し、この主張を裏付ける多くの証拠を列挙しています。
記事内の一部の見解は正確ではなくなりました。たとえば、この記事では、Math.random() 関数は乱数の適切なソースではないため、暗号化に必要な十分な乱数を取得することは不可能であると述べています。 Math.random() 関数は確かに乱数の良いソースではありません。最新のブラウザでは、十分な数の乱数を取得するための crypto.getRandomValues() 関数がすでに提供されています。
このスレッドには、JavaScript 暗号化が悪い考えであることを証明する例がかなりありますが、それは理にかなっています。この回答は、最初の投稿の多くの議論に有効に反論し、JavaScript 暗号化の 2 つの有効な使用例、つまりエンドツーエンドのメッセージ暗号化 (つまり、ホスト アクセスから保護するアプリケーション) と安全なリモート パスワード認証を指摘しています。これらはまさに Opal 暗号化の使用シナリオであるため、JavaScript 暗号化を使用するのは非常に自然です。
JavaScript 暗号化は高速に可能
最近まで、JavaScript は安全な暗号化に必要な複雑な計算を実行するのに時間がかかりました。これにより、多くのアプリケーションがプラグインによって提供される暗号化機能に依存することになりますが、これは移植性がなく、ユーザーにとって迷惑です。
幸いなことに、JavaScript のパフォーマンスは近年大幅に向上したため、暗号化操作に完全に JavaScript を使用することが可能になりました。現在、選択できる JavaScript 暗号化ライブラリは多数あります (リンク 1、リンク 2、リンク 3、リンク 4、リンク 5、リンク 6、リンク 7、リンク 8、リンク 9)。
そこで、どの図書館を選ぶかが問題になります。
NaCl、信頼性の高い C 言語暗号化ライブラリ
NaCl (「ソルト」と発音) は、対称鍵暗号化、復号化、および公開鍵署名認証のためのアプリケーション関数を提供する C 言語ライブラリです。これは暗号学者によって書かれており、暗号コミュニティではよく知られており、信頼されています。問題の 1 つは、NaCl が JavaScript ではなく C で記述されていることです。
js-NaCl: NaCl を JavaScript にコンパイルする
幸いなことに、NaCl を LLVM バイトコードにコンパイルし、emscripten を使用してこれらのバイトコードを JavaScript にコンパイルできます。さらに、LLVM コンパイラはコンパイル中に多くの最適化を実行できるため、結果の JavaScript コードも最適化されます。したがって、NaCl ライブラリを JavaScript にコンパイルして、ブラウザーで実行できるようにすることができます。
js-nacl プロジェクトはまさに、JavaScript にコンパイルされた NaCl 暗号化ライブラリです。
asm.js は高速です!
さらに良いことに、emscripten によってコンパイルされたコードは、asm.js とも呼ばれる JavaScript のサブセットです。 asm.js は、JavaScript とよく似たアセンブリ言語と考えることができます。ブラウザーが asm.js のコード ブロックを検出すると、それを効率的なマシン コードにコンパイルし、ネイティブ コードに近い速度で実行します。
現在、asm.js の最適化をサポートしているのは Firefox ブラウザーのみです。これにより、Firefox での js-nacl 暗号化と復号化が非常に高速になり、特定の操作に応じて Chrome ブラウザよりも 2 ~ 8 倍速くなります。しかし、Chrome の場合でも、js-nacl は高速であり、テストした他のすべての暗号化ライブラリを上回っています。
NaCl のような信頼できる暗号化ライブラリと最新のブラウザでの高速実行により、Opal のような Web アプリケーションで js-nacl ライブラリを使用することは良いアイデアになります。
同じ理由で、Opal は emscripten によってコンパイルされた scrypt ライブラリの asm.js バージョンを使用してキーを拡張します (この記事では有効になっています)。プロジェクトのメンテナが提供する js-nacl と js-scrypt のパフォーマンスの比較を確認できます。また、ブラウザーのバージョン間のパフォーマンスの違いを理解するために、js-nacl の jsperf テストも実施しました。必要に応じて試してみることもできます。