DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ファイルやフォルダをNTFS暗号化する

エクスプローラでファイルやフォルダのプロパティを表示させると、その「属性」の「詳細設定」に「内容を暗号化してデータをセキュリティで保護する」という項目があります。これを適用すると、ファイルが暗号化され、暗号化属性が付きます。このような暗号化機能は、Windows 2000以降のNTFSでサポートされています。

ここでは、このようにファイルやフォルダにNTFS暗号化属性を付ける方法を紹介します。

.NET Framework 2.0以降で、File.Encryptメソッドを使う

.NET Framework 2.0からは、File.EncryptメソッドでファイルのNTFS暗号化を行えます。ファイルだけでなく、フォルダに暗号化属性を付けることもできます。復号化する(暗号化属性を外す)には、File.Decryptメソッドを使います。

フォルダを暗号化したとき、そのときにフォルダにあるファイルは暗号化されません。暗号化されたフォルダに新しくファイルを作成すると、そのファイルは暗号化されます。

VB.NET
コードを隠すコードを選択
Dim filePath As String = "C:\test\1.txt"

'ファイルを暗号化する(暗号化属性をつける)
'NTFSのみで有効
System.IO.File.Encrypt(filePath)

'ファイルを復号化する(暗号化属性をはずす)
'暗号化したアカウントだけが復号化できる
System.IO.File.Decrypt(filePath)
C#
コードを隠すコードを選択
string filePath = "C:\\test\\1.txt";

//ファイルを暗号化する(暗号化属性をつける)
//NTFSのみで有効
System.IO.File.Encrypt(filePath);

//ファイルを復号化する(暗号化属性をはずす)
//暗号化したアカウントだけが復号化できる
System.IO.File.Decrypt(filePath);

Win32 APIのEncryptFile関数を使う

.NET Framework 1.1以下では、Win32 APIのEncryptFile関数を直接使います。復号化は、DecryptFile関数です。

以下に、ファイルやフォルダをNTFS暗号化するEncryptメソッドと、復号化するDecryptメソッドを作成する例を示します。

VB.NET
コードを隠すコードを選択
'Imports System.Runtime.InteropServices

<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function EncryptFile(ByVal lpFileName As String) As _
    <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function DecryptFile(ByVal lpFileName As String, _
    ByVal dwReserved As Integer) As _
    <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

''' <summary>
''' ファイルやフォルダをNTFS暗号化する
''' </summary>
''' <param name="filePath">暗号化するファイルのパス</param>
Public Shared Sub Encrypt(ByVal filePath As String)
    If Not EncryptFile(filePath) Then
        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error())
    End If
End Sub

''' <summary>
''' NTFS暗号化されたファイルやフォルダを復号化する
''' </summary>
''' <param name="filePath">復号化するファイルのパス</param>
Public Shared Sub Decrypt(ByVal filePath As String)
    If Not DecryptFile(filePath, 0) Then
        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error())
    End If
End Sub
C#
コードを隠すコードを選択
//using System.Runtime.InteropServices;

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EncryptFile(string lpFileName);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DecryptFile(string lpFileName, int dwReserved);

/// <summary>
/// ファイルやフォルダをNTFS暗号化する
/// </summary>
/// <param name="filePath">暗号化するファイルのパス</param>
public static void Encrypt(string filePath)
{
    if (!EncryptFile(filePath))
    {
        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
    }
}

/// <summary>
/// NTFS暗号化されたファイルやフォルダを復号化する
/// </summary>
/// <param name="filePath">復号化するファイルのパス</param>
public static void Decrypt(string filePath)
{
    if (!DecryptFile(filePath, 0))
    {
        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
    }
}

cipher.exeを使用する

DOSコマンド"cipher"を使用して、ファイルやフォルダのNTFS暗号化ができます。

フォルダ"C:\test"と、それ以下のフォルダとファイルを暗号化する例を示します。

VB.NET
コードを隠すコードを選択
Dim psi As New System.Diagnostics.ProcessStartInfo()
psi.FileName = "cipher.exe"
'コマンドラインを指定する
psi.Arguments = "/e /s:""C:\test"" /a"
'ウィンドウを表示しないようにする
psi.UseShellExecute = False
psi.CreateNoWindow = True
'実行する
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(psi)
C#
コードを隠すコードを選択
System.Diagnostics.ProcessStartInfo psi =
    new System.Diagnostics.ProcessStartInfo();
psi.FileName = "cipher.exe";
//コマンドラインを指定する
psi.Arguments = @"/e /s:""C:\test"" /a";
//ウィンドウを表示しないようにする
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
//実行する
System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi);

Windows XPで「cipher /?」を実行したときに表示されるcipher.exeの使用法は、以下の通りです。

NTFS パーティション上のディレクトリ [ファイル] の暗号化を表示または変更します。

  CIPHER [/E | /D] [/S:ディレクトリ] [/A] [/I] [/F] [/Q] [/H] [パス名 [...]]

  CIPHER /K

  CIPHER /R:ファイル名

  CIPHER /U [/N]

  CIPHER /W:ディレクトリ

  CIPHER /X[:EFS ファイル] [ファイル名]

    /A        ファイルおよびディレクトリに対して操作を実行します。
              親ディレクトリが暗号化されていない場合、暗号はファイルが
              修正されると解除されます。ファイルと親ディレクトリの両方を
              暗号化することをお勧めします。
    /D        指定されたディレクトリの暗号化を解除します。後で追加された
              ファイルが暗号化されないようにディレクトリをマークします。
    /E        指定されたディレクトリを暗号化します。後で追加された
              ファイルが暗号化されるようにディレクトリをマークします。
    /F        暗号化済みのオブジェクトも含めて、指定されたすべてのオブジェ
              クトを強制的に暗号化します。既定では暗号化済みのオブジェ
              クトはスキップされます。
    /H        隠しファイルやシステム属性のファイルを表示します。
              既定ではこれらのファイルは省略されます。
    /I        エラーが発生しても指定された操作を実行し続けます。既定では、
              エラーが発生すると CIPHER は停止されます。
    /K        CIPHER を実行しているユーザー用に新しいファイル暗号化キーを
              作成します。このオプションが指定されると、その他のオプションは
              すべて無視されます。
    /N        このオプションは /U でのみ動作します。このオプションにより、
              キーが更新されなくなります。ローカル ドライブ上のすべての暗号
              化ファイルを探すために使用されます。
    /Q        重要な情報だけを報告します。
    /R        EFS 回復エージェント キーと証明書を作成してから、それらを .PFX
              ファイル (証明書と秘密キー) と .CER ファイル (証明書のみ) に
              書き込みます。管理者は、ユーザーの回復エージェントを作成する
              ために.CER の内容を EFS 回復ポリシーに追加し、個々のファイル
              を回復するために .PFX ファイルをインポートすることができます。
    /S        指定されたディレクトリとすべてのサブディレクトリに
              対して指定された操作を実行します。
    /U        ローカル ドライブのすべての暗号化ファイルを参照しようとします。
              これにより、現在のユーザーのファイル暗号化キー、または回復
              エージェント キーに変更があった場合、これらが更新されます。
              このオプションは /N 以外のほかのオプションでは動作しません。
    /W        ボリュームで利用可能な未使用のディスクから、データを削除します。
              このオプションを選んだ場合は、ほかのオプションはすべて無視されま
              す。ローカル ボリューム上のどの場所にあるディレクトリでも指定す
              ることができます。ディレクトリがマウント ポイントである場合、
              または別のボリュームのディレクトリを指し示す場合は、そのボリュー
              ムのデータが削除されます。
    /X        EFS 証明書とキーのバックアップをファイルのファイル名に作成しま
              す。EFS ファイルが指定されている場合は、暗号化に使われている現在
              のユーザーの証明書のバックアップが作成されます。指定されていない
              場合は、ユーザーの現在の EFS 証明書とキーのバックアップが作成
              されます。


    ディレクトリ  ディレクトリのパスです。
    ファイル名    拡張子を伴わないファイル名です。
    パス名        パターン、ファイル、またはディレクトリを指定します。
    EFS ファイル   暗号化されたファイルのパスです。

    パラメータを指定せずに CIPHER を実行すると、現在のディレクトリと
    ディレクトリに含まれるすべてのファイルの暗号化状態を表示します。
    複数のディレクトリ名やワイルドカードを指定できます。複数のパラメータ
    を指定する場合は、パラメータをスペースで区切ってください。
  • 履歴:
  • 2010/9/20 「ファイルの属性を取得、設定する」から分離。Win32 APIによる方法を追加。
  • 2015/1/29 「cipher.exe」とすべきところが「shutdown.exe」となっていたのを修正。
  • 2015/2/2 cipher.exeを使用するサンプルで「psi.UseShellExecute = False」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。