Encrypting Files using DPAPI
In one of my current projects (yes, there are more at the moment and yes that is the reason why it’s a bit quiet around here) i neede to write an encrypted file to the hard disc using DPAPI (Data Protection API). After I unsuccessfully searched the web and the msdn (the sample reads all bytes to the buffer at once - not so nice), I wrote the following sample app:
using System;
using System.IO;
using System.Security.Cryptography;
public class DataProtectionSample
{
public static void Main()
{
using(MemoryStream ms = new MemoryStream())
{
StreamWriter swriter = new StreamWriter(ms);
swriter.WriteLine("Text to encrypt to file.");
swriter.Flush();
Console.WriteLine("Protecting data ...");
DataProtection.Protect("D:\\_temp\\DPAPI.dat", ms, false);
}
Console.WriteLine("Unprotecting data ...");
using(MemoryStream ms2 =
(MemoryStream)DataProtection.Unprotect("D:\\_temp\\DPAPI.dat", false))
{
StreamReader sreader = new StreamReader(ms2);
Console.WriteLine("");
Console.WriteLine("Decrypted string: " + sreader.ReadToEnd());
}
Console.ReadLine();
}
}
public class DataProtection
{
private static byte[] _additionalEntropy = { 9, 8, 7, 6, 5 };
private static int _bufferLength = 1024;
public static void Protect(
string filename,
Stream stream,
bool machineLevel)
{
if (File.Exists(filename))
{
File.Delete(filename);
}
using (FileStream fs = new FileStream(filename, FileMode.CreateNew))
{
byte[] buffer = new byte[_bufferLength];
long byteCount;
stream.Position = 0;
while ((byteCount =
stream.Read(buffer, 0, buffer.Length)) > 0)
{
buffer =
ProtectedData.Protect(
buffer,
_additionalEntropy,
((machineLevel)
? DataProtectionScope.LocalMachine
: DataProtectionScope.CurrentUser));
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
}
}
}
public static Stream Unprotect(string filename, bool machineLevel)
{
MemoryStream ms = new MemoryStream();
using (FileStream fs = new FileStream(filename, FileMode.Open))
{
byte[] buffer = new byte[_bufferLength + 146];
long byteCount;
while ((byteCount =
fs.Read(buffer, 0, buffer.Length)) > 0)
{
buffer =
ProtectedData.Unprotect(
buffer,
_additionalEntropy,
((machineLevel)
? DataProtectionScope.LocalMachine
: DataProtectionScope.CurrentUser));
ms.Write(buffer, 0, buffer.Length);
ms.Flush();
}
}
ms.Position = 0;
return ms;
}
}