ファイルのすべての痕跡を安全に削除するために、なぜファイルを複数回上書きするのでしょうか?
質問
Eraser などの消去プログラムでは、データを 36 回上書きすることをお勧めします。
私の理解では、すべてのデータはハードドライブに 1 または 0 として保存されます。
ランダムな 1 と 0 の上書きがファイル全体に対して 1 回実行された場合、元のファイルの痕跡をすべて削除するのに十分ではないのはなぜでしょうか。
解決
以前は 0 であったが、その後「1」に変更されたハードドライブのビットは、以前は 1 であり、その後再び 1 に書き込まれたビットよりもわずかに弱い磁界を持っています。高感度の機器を使用すると、強度のわずかな変化を測定することで、各ビットの以前の内容をある程度の精度で識別できます。結果は正確には正しくなく、エラーが発生しますが、以前の内容のかなりの部分を取得できます。
35 回もビット上に走り書きをする頃には、そこに何があったのかを識別することは事実上不可能になります。
編集: 現代的な分析 上書きされた単一ビットを 56% の精度でしか回復できないことを示しています。バイト全体を復元しようとしても、正確な確率は 0.97% にすぎません。つまり、都市伝説を繰り返していたのです。フロッピー ディスクなどのメディアを使用する場合は、複数回の上書きが必要になる場合がありますが、ハードディスクの場合はその必要がありません。
他のヒント
ダニエル・フィーンバーグ氏(私立国立経済研究所の経済学者)は、現代のハードドライブから上書きされたデータが復元される可能性は「都市伝説」に等しいと主張しています。
したがって、理論的にはファイルを 0 で 1 回上書きするだけで十分です。
従来の用語では、ディスクに 1 が書き込まれるとメディアは 1 を記録し、0 が書き込まれるとメディアは 0 を記録します。ただし、実際の効果は、ゼロが 1 で上書きされる場合は 0.95 が得られ、1 が 1 で上書きされる場合は 1.05 が得られることに近づきます。通常のディスク回路は、これらの値が両方とも 1 として読み取られるように設定されていますが、特殊な回路を使用すると、以前の「層」に何が含まれていたかを解明することができます。上書きされたデータの少なくとも 1 つまたは 2 つのレイヤーの復元は、高品質デジタル サンプリング オシロスコープでアナログ ヘッド エレクトロニクスから信号を読み取り、サンプリングされた波形を PC にダウンロードしてソフトウェアで分析することによって実行するのは、それほど難しいことではありません。以前に記録された信号を復元します。ソフトウェアが行うことは、「理想的な」読み取り信号を生成し、それを実際に読み取られた信号から減算し、前の信号の残存物を差分として残すことです。市販のハードドライブのアナログ回路は、信号のサンプリングに使用されるオシロスコープの回路の品質には遠く及ばないため、ハードドライブの電子機器によって利用されない多くの追加情報を回復する機能が存在します(ただし、新しいものでは、大量の信号処理を必要とする PRML (後述) などのチャネル コーディング技術では、オシロスコープなどの単純なツールを使用してデータを直接復元することはもはや不可能です)
物理ディスク上のデータのセクターを想像してください。このセクター内には、セクターに格納されているデータのビットをエンコードする磁気パターン (ストリップ) があります。このパターンは、ディスクがその下で回転している間、多かれ少なかれ静止している書き込みヘッドによって書き込まれます。さて、ハードドライブがデータストレージデバイスとして適切に機能するには、新しい磁気パターンストリップがセクターに書き込まれるたびに、後で読み取れるようにそのセクター内の磁気パターンをリセットする必要があります。ただし、以前の磁気パターンの痕跡をすべて完全に消去する必要はなく、十分に良好である必要があります(そして、今日使用されている誤り訂正の量では、十分に良好である必要はありません)。書き込みヘッドは、特定のセクター上を前回通過したときと同じトラックを常に通るとは限らないことを考慮してください (書き込みヘッドは、左右に少し傾いている可能性があり、一方または他方にわずかな角度でセクター上を通過する可能性があります)振動などに影響されます)
得られるのは、最後のデータ書き込みに対応する最も強いパターンを含む一連の磁気パターン層です。適切な計測器を使用すると、このパターンの階層化を十分詳細に読み取ることができ、古い層のデータの一部を特定できる可能性があります。
データがデジタルであることは役に立ちます。特定の層のデータを抽出すると、それをディスクに書き込むために使用された磁気パターンを正確に判断し、読み取り値からそれを差し引くことができるからです(そして、次のデータでそれを行うことができます)。レイヤー、そして次)。
これが欲しい理由は、 ない ハードディスクですが、 SSD. 。OS やファイル システム ドライバーに通知せずにクラスターを再マップします。これはウェアレベリングの目的で行われます。したがって、書き込まれた 0 ビットが前の 1 とは異なる場所に書き込まれる可能性が非常に高くなります。SSD コントローラーを取り外して生のフラッシュ チップを読み取ることは、企業スパイでも十分に手の届く範囲にあります。ただし、ディスク全体を 36 回上書きすると、ウェアレベリングはすべてのスペア ブロックを数回繰り返した可能性があります。
「データリマネンス」攻撃の可能性と実際の実現可能性に関するかなりの参照セットがあります ウィキペディア。そこでは国防総省および NIST の基準と推奨事項も引用されています。要するに、磁気メディアから上書きされたデータを回復することは可能ですが、ますます困難になっています。それにもかかわらず、一部の(米国政府の)標準では依然として少なくとも複数回の上書きが必要です。一方、デバイスの内部はますます複雑になり、上書きした後でも、ドライブまたはソリッド ステート デバイスに予期せぬコピーが存在する可能性があります (不良ブロックの処理やフラッシュ ウェア レベリングについて考えてください (ピーター・ガットマンを参照)。したがって、本当に心配している人は依然としてドライブを破壊します。
ここで見ているのは、「データリマネンス」と呼ばれます。実際、繰り返し上書きするテクノロジーのほとんどは、実際に必要なこと以上のことを(無害に)しています。データが上書きされたディスクからデータを回復する試みはこれまでにも行われてきましたが、少数の実験室ケースを除いて、そのような技術が成功した例は実際にはありません。
回復方法について話すとき、主に磁気力顕微鏡検査が偶発的な上書きを回避する特効薬であると考えられますが、これでも成功の記録はなく、どのような場合でも、領域全体にバイナリデータの適切なパターンを書き込むことで破棄できます。磁気メディア (単純な 0000000000 ではなく)。
最後に、あなたが言及している 36 (実際には 35) の上書きは、今日では時代遅れで不必要であると認識されています。この技術 (ガットマン法として知られています) は、テクノロジで使用されるさまざまな (通常はユーザーに知られていない) エンコード方式に対応するように設計されているためです。 RLL や MFM など、いずれにしても遭遇する可能性は低いです。米国政府のガイドラインでも、データを削除するには 1 回の上書きで十分であると記載されていますが、管理上の目的でこれを「サニタイズ」として許容できるとは考えていません。この差異の原因として考えられるのは、「不良」セクタはディスク ハードウェアによって不良とマークされ、上書きの時期になっても適切に上書きされない可能性があるため、ディスクの目視検査でこれらのセクタを回復できる可能性が残されているということです。地域。
結局のところ、1010101010101010 またはかなりランダムなパターンで書き込むだけで、既知の技術では回復できないほどデータを消去するのに十分です。
私は、ファイルが以前にディスク上の別の物理的な場所に保存されていた可能性がなぜ考慮されないのか、いつも疑問に思っていました。
たとえば、デフラグが行われたばかりの場合、ディスク上の別の場所に簡単に回復できるファイルのコピーが存在する可能性があります。
これは私がまとめた Gutmann 消去の実装です。暗号化乱数ジェネレーターを使用して、ランダム データの強力なブロックを生成します。
public static void DeleteGutmann(string fileName)
{
var fi = new FileInfo(fileName);
if (!fi.Exists)
{
return;
}
const int GutmannPasses = 35;
var gutmanns = new byte[GutmannPasses][];
for (var i = 0; i < gutmanns.Length; i++)
{
if ((i == 14) || (i == 19) || (i == 25) || (i == 26) || (i == 27))
{
continue;
}
gutmanns[i] = new byte[fi.Length];
}
using (var rnd = new RNGCryptoServiceProvider())
{
for (var i = 0L; i < 4; i++)
{
rnd.GetBytes(gutmanns[i]);
rnd.GetBytes(gutmanns[31 + i]);
}
}
for (var i = 0L; i < fi.Length;)
{
gutmanns[4][i] = 0x55;
gutmanns[5][i] = 0xAA;
gutmanns[6][i] = 0x92;
gutmanns[7][i] = 0x49;
gutmanns[8][i] = 0x24;
gutmanns[10][i] = 0x11;
gutmanns[11][i] = 0x22;
gutmanns[12][i] = 0x33;
gutmanns[13][i] = 0x44;
gutmanns[15][i] = 0x66;
gutmanns[16][i] = 0x77;
gutmanns[17][i] = 0x88;
gutmanns[18][i] = 0x99;
gutmanns[20][i] = 0xBB;
gutmanns[21][i] = 0xCC;
gutmanns[22][i] = 0xDD;
gutmanns[23][i] = 0xEE;
gutmanns[24][i] = 0xFF;
gutmanns[28][i] = 0x6D;
gutmanns[29][i] = 0xB6;
gutmanns[30][i++] = 0xDB;
if (i >= fi.Length)
{
continue;
}
gutmanns[4][i] = 0x55;
gutmanns[5][i] = 0xAA;
gutmanns[6][i] = 0x49;
gutmanns[7][i] = 0x24;
gutmanns[8][i] = 0x92;
gutmanns[10][i] = 0x11;
gutmanns[11][i] = 0x22;
gutmanns[12][i] = 0x33;
gutmanns[13][i] = 0x44;
gutmanns[15][i] = 0x66;
gutmanns[16][i] = 0x77;
gutmanns[17][i] = 0x88;
gutmanns[18][i] = 0x99;
gutmanns[20][i] = 0xBB;
gutmanns[21][i] = 0xCC;
gutmanns[22][i] = 0xDD;
gutmanns[23][i] = 0xEE;
gutmanns[24][i] = 0xFF;
gutmanns[28][i] = 0xB6;
gutmanns[29][i] = 0xDB;
gutmanns[30][i++] = 0x6D;
if (i >= fi.Length)
{
continue;
}
gutmanns[4][i] = 0x55;
gutmanns[5][i] = 0xAA;
gutmanns[6][i] = 0x24;
gutmanns[7][i] = 0x92;
gutmanns[8][i] = 0x49;
gutmanns[10][i] = 0x11;
gutmanns[11][i] = 0x22;
gutmanns[12][i] = 0x33;
gutmanns[13][i] = 0x44;
gutmanns[15][i] = 0x66;
gutmanns[16][i] = 0x77;
gutmanns[17][i] = 0x88;
gutmanns[18][i] = 0x99;
gutmanns[20][i] = 0xBB;
gutmanns[21][i] = 0xCC;
gutmanns[22][i] = 0xDD;
gutmanns[23][i] = 0xEE;
gutmanns[24][i] = 0xFF;
gutmanns[28][i] = 0xDB;
gutmanns[29][i] = 0x6D;
gutmanns[30][i++] = 0xB6;
}
gutmanns[14] = gutmanns[4];
gutmanns[19] = gutmanns[5];
gutmanns[25] = gutmanns[6];
gutmanns[26] = gutmanns[7];
gutmanns[27] = gutmanns[8];
Stream s;
try
{
s = new FileStream(
fi.FullName,
FileMode.Open,
FileAccess.Write,
FileShare.None,
(int)fi.Length,
FileOptions.DeleteOnClose | FileOptions.RandomAccess | FileOptions.WriteThrough);
}
catch (UnauthorizedAccessException)
{
return;
}
catch (IOException)
{
return;
}
using (s)
{
if (!s.CanSeek || !s.CanWrite)
{
return;
}
for (var i = 0L; i < gutmanns.Length; i++)
{
s.Seek(0, SeekOrigin.Begin);
s.Write(gutmanns[i], 0, gutmanns[i].Length);
s.Flush();
}
}
}
フォーマットした後でもハードドライブからデータを読み取ることができる「ディスク修復」タイプのアプリケーションやサービスがあるため、本当に何かを安全に消去する必要がある場合は、ランダムな 1 と 0 で 1 回上書きするだけでは十分ではありません。
平均的なユーザーにとってはこれで十分すぎると思いますが、高度なセキュリティ環境 (政府、軍など) にいる場合は、かなり効果的に保証できる、より高いレベルの「削除」が必要になります。ドライブからデータを回復することはできません。
米国には、機密情報の消去に関する要件があります(つまり、極秘情報)はドライブを破壊することです。基本的に、ドライブは巨大な磁石を備えた機械に組み込まれ、廃棄する場合はドライブを物理的に破壊することになります。これは、ドライブ上の情報が読み取られ、何度も上書きされる可能性があるためです。
これを参照してください: ガットマンの論文
すべての 0 に 1 が書き込まれ、すべての 1 に 0 が書き込まれてから、すべてをゼロにするだけでビットを反転するだけで、磁界内の変数がすべて削除され、2 パスしかかかりません。