0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブラウザだけで完結!Web Crypto API + Tailwind CSS で作るセキュアなハイブリッド暗号(RSA-OAEP + AES-GCM)ツール

0
Last updated at Posted at 2026-10-22

ブラウザだけで完結!Web Crypto API + Tailwind CSS で作るセキュアなハイブリッド暗号(RSA-OAEP + AES-GCM)ツール

はじめに

ブラウザ上だけでファイル単位の暗号化・復号を行いたい、かつ外部の重い暗号ライブラリ(node-forgeなど)への依存やサーバー通信を一切排除したい——というモチベーションから、Web Crypto API (window.crypto.subtle) を用いた完全ブラウザネイティブな単一HTMLファイル(HTML+CSS+JS)の暗号化ツールを自作しました。

デモページ

操作例動画:
パスワードありAES:
crypt000.gif
パスワードなしRSA:
crypt001.gif

この記事では、実装にあたって工夫したポイントや、実用性を高めるための設計上のアプローチについてご紹介します。


🛠 主な仕様とアーキテクチャ

  • ハイブリッド暗号方式: ランダム鍵モードでは 2048bit RSA-OAEP で AES-GCM 共通鍵をラップし、ファイル本体は高速な AES-GCM (256bit) で暗号化します。
  • パスワード暗号モード: パスワードが入力された場合は PBKDF2 (SHA-256 / 100,000回反復) により鍵を導出し、RSA鍵なしで直接 AES-GCM 暗号化を行います。
  • 完全スタンドアロン: 外部ライブラリを一切使わず、ブラウザ標準APIとCDNのTailwind CSS(デザイン用)のみで動作するため、オフライン環境でもそのまま利用できます。

✨ 開発における3つの工夫ポイント

1. 外部ライブラリ依存の完全排除とWeb標準への全面移行

私が以前作ったレガシーなJavaプログラム等との互換性を意識してサードパーティ製ライブラリ(node-forgeなど)を使うアプローチをとっていましたが、パディング仕様やバイナリ構造の差異でトラブルが起きがちでした。
今回は思い切ってそれらを捨て、ブラウザ標準の window.crypto.subtle を全面採用。これにより、コードの透明性が上がり、セキュリティ的にもモダンで安全な実装になりました。

2. 単一ファイル(Single-File HTML)による圧倒的なポータビリティ

ツールとしての利便性を最大化するため、HTML、UIデザイン、暗号化・復号のロジック、ログ出力機能のすべてを1つのHTMLファイルに凝縮しました。
バックエンドサーバーへのファイル送信はゼロ(完全クライアントサイド処理)であり、ローカルに保存してダブルクリックするだけで、どこでも即座に安全な暗号・復号ツールとして機能します。

3. ドラッグ&ドロップによる「ファイル拡張子自動判定」と「複数ファイル一括処理」

実務や日常のファイル管理を想定し、UIの操作性を徹底的にシンプルにしました。

  • ドロップされたファイルの拡張子が .enc なら自動で復号、それ以外なら暗号化して .enc を付与して自動ダウンロードします。
  • さらに、複数ファイルのドラッグ&ドロップやファイル選択(multiple)に対応させ、ループ処理で順番に非同期実行 (async/await) することで、大量のファイルもストレスなく一括処理できるようにしました。
// 複数ファイル処理のループ実装例
async function handleFiles(files) {
    log(`\n=== 複数ファイル処理開始: ${files.length}件 ===`);
    for (let i = 0; i < files.length; i++) {
        const file = files[i];
        if (/\.enc$/i.test(file.name)) {
            await processDecrypt(file);
        } else {
            await processEncrypt(file);
        }
    }
    log(`=== すべてのファイル処理が完了しました ===`);
}


📦 バイナリフォーマットの設計(自己完結型)

ランダム鍵モード(パスワードなし)では、Java版のように「別途 enckey.data ファイルを管理する」といった煩雑さを解消するため、出力される .enc ファイルの内部にヘッダーとして必要な情報をすべてカプセル化しました。

バイナリの構造は以下のようになっています:

[1byte: フラグ (0=ランダム鍵+RSA, 1=パスワード)]
[16bytes: Salt (PBKDF2用)]
[12bytes: IV (AES-GCM用)]
[2bytes (LE): ラップされたAES鍵の長さ]
[N bytes: RSAで暗号化されたAES共通鍵 (ランダム鍵モード時のみ)]
[Rest: 暗号化されたファイル本体 (Ciphertext)]

これにより、「暗号化された .enc ファイル」と「対応する秘密鍵 (prvkey.pem)」のペアだけがあれば、どこへ持ち運んでも確実に復号できる可搬性を実現しています。


おわりに

Web Crypto APIを活用することで、特別なビルド環境やサーバーサイドの実装を用意しなくても、ブラウザだけで実用的な高セキュリティツールが作れるのは非常に強力です。

「ちょっとしたファイルの暗号化を、安全かつオフラインでサクッと行いたい」というユースケースには最適な構成になりました。今後も必要に応じてユーティリティを追加・ブラッシュアップしていきたいと思います。

デモページ

crypt000.png

操作例動画:
パスワードありAES:
crypt000.gif
パスワードなしRSA:
crypt001.gif


作者

GitHub: https://github.com/NAS6mixfoolv
X(旧Twitter): https://x.com/NAS6_oxo
作者HP: https://nas6.net

気に入っていただけたら GitHub に ⭐ をいただけると嬉しいです!


0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?