AIプロンプトにおける定型外秘密キー等の漏洩問題
ChatGPT、Claude、Gemini にエラーログや設定ファイル(.env / config.json)を貼り付けてデバッグする際、sk-proj-... や AKIA... のような定型プレフィックスを持つキーであれば正規表現で簡単にマスクできます。
しかし実務のコードベースには、特定のプレフィックスを持たない独自のWebhook署名シークレット、JWT署名鍵、社内APIトークンが大量に含まれています。さらに、LLMが回答の中で {{ EMAIL_1 }} のようにスペースを入れたり順番を入れ替えたりした際、手作業で元の値へ書き戻すのは非常に手間がかかります。
本記事では、外部サーバーへ一切通信せずブラウザ内(Vanilla JS)だけで「シャノン・エントロピー(情報量 H(X))」を計算して未知の秘密鍵を自動検知・仮名化し、LLMによる表記ゆれ(Mutation)も吸収してワンクリックで元の値へ復元する仕組みと、それを実装した無料Webツール『MaskFlow AI』のアーキテクチャを紹介します。
1. シャノン・エントロピー(Shannon Entropy)による高ランダム性文字列の検知
情報理論におけるシャノン・エントロピー H(X) は、文字列内の各文字の出現確率 P(x) から「1文字あたりの平均情報量(ビット数)」を算出する指標です。
- 通常の英単語や変数名(例:
"authentication_service_url"):文字の偏りがあるため H(X) = 2.8 〜 3.5 bits/char に収まります。 - 暗号論的に生成された秘密鍵やトークン(例:
"K9mP4xQ8vL2nZ7wR5tY1cB6fH3jM9pQ2"):文字が一様に分散し、大文字・小文字・数字・記号が混在するため H(X) >= 3.85 bits/char となります。
JavaScriptによる軽量エントロピー算出&文字種遷移フィルタの実装
ブラウザのメインスレッドをブロックせずリアルタイムに判定するため、以下の2段階フィルタを実装しています。
// 1. シャノン・エントロピー H(X) の算出 (bits per character)
function calcShannonEntropy(str) {
if (!str || str.length === 0) return 0;
const freq = {};
for (let i = 0; i < str.length; i++) {
const ch = str.charAt(i);
freq[ch] = (freq[ch] || 0) + 1;
}
const len = str.length;
let entropy = 0;
for (const ch of Object.keys(freq)) {
const p = freq[ch] / len;
entropy -= p * Math.log2(p);
}
return Math.round(entropy * 100) / 100;
}
// 2. 文字種クラス(小文字・大文字・数字・記号)の混在チェック
function hasMixedSecretClasses(str) {
let classes = 0;
if (/[a-z]/.test(str)) classes++;
if (/[A-Z]/.test(str)) classes++;
if (/[0-9]/.test(str)) classes++;
if ([/_|-|\+|\$|\./].some((r) => r.test(str))) classes++;
return classes >= 3;
}
この2つを組み合わせることで、クォート("..." または '...')で囲まれた20〜64文字の文字列のうち、calcShannonEntropy(candidate) >= 3.85 かつ hasMixedSecretClasses(candidate) === true のものだけを「未知の高エントロピー機密({{SECRET_1}})」として高精度に抽出できます。
2. LLMによるトークン変異(Mutation)と順序入れ替えを吸収する3層アンマスク設計
LLMに仮名化テキストを渡すと、出力時に「段落の順序入れ替え」や「プレースホルダーの微妙な書き換え」が発生することがあります。これを以下の3層で解決しています。
-
順序に依存しないKey-Value辞書:配列インデックスではなく トークン ⇔ 元の値 のハッシュ辞書で保持することで、順序が変わっても何回繰り返されても100%正確に復元します。
-
文脈維持ダミー別名(Synthetic Alias)モード:{{EMAIL_1}} の代わりに user01@example.org や 10.240.0.1 といった構文的に正しいダミー値を渡すことで、SQLやTypeScript生成時のLLMの構文エラーを防ぎます。
-
ファジー耐変異マッチャー(v2.1):万一LLMが {{ EMAIL_1 }}(空白混入)や [EMAIL_1](括弧の変化)、{{email_1}}(小文字化)のように出力しても、正規表現のファジーマッチングで自動的に元の機密値へ復元します。
3. 実機デモ(100%クライアントサイド実行・通信ゼロ)
上記のハイブリッド検知&ワンクリック復元エンジンを、ログイン不要・通信ゼロの単一Webアプリとして無料公開しています。
👉 GitHubリポジトリ・デモ詳細: https://github.com/mint69-ops/maskflow-ai
ぜひ日々のAIコーディングやログ解析のセキュリティ対策として試してみてください!
![FireShot Capture 001 - MaskFlow AI — 100% Client-Side Prompt Sanitizer, Reversible Unmaske_ - [maskflow-ai.pages.dev].png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F4519596%2Fadf016e5-71c8-4a8d-ae4a-b62cf9edd895.png?ixlib=rb-4.1.1&auto=format&gif-q=60&q=75&s=b7e56066a79b92ff51936fe45e1aa628)