This is the DPAPI accessor ripped from MSDN:
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace YourNamespaceHere {
/// <summary>
/// Provides access to the Win32 DPAPI; exposes
the Encrypt & Decrypt methods
/// </summary>
public class DataProtector {
[DllImport("Crypt32.dll",
SetLastError=true,
CharSet=System.Runtime.InteropServices.CharSet.Aut o)]
private static extern bool
CryptProtectData(
ref DATA_BLOB pDataIn,
String szDataDescr,
ref DATA_BLOB pOptionalEntropy,
IntPtr pvReserved,
ref CRYPTPROTECT_PROMPTSTRUCT
pPromptStruct,
int dwFlags,
ref DATA_BLOB pDataOut);
[DllImport("Crypt32.dll",
SetLastError=true,
CharSet=System.Runtime.InteropServices.CharSet.Aut o)]
private static extern bool
CryptUnprotectData(
ref DATA_BLOB pDataIn,
String szDataDescr,
ref DATA_BLOB pOptionalEntropy,
IntPtr pvReserved,
ref CRYPTPROTECT_PROMPTSTRUCT
pPromptStruct,
int dwFlags,
ref DATA_BLOB pDataOut);
[DllImport("kernel32.dll",
CharSet=System.Runtime.InteropServices.CharSet.Aut o)]
private unsafe static extern int
FormatMessage(int dwFlags,
ref IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
ref String lpBuffer,
int nSize,
IntPtr *Arguments);
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
internal struct DATA_BLOB {
public int cbData;
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
internal struct
CRYPTPROTECT_PROMPTSTRUCT {
public int cbSize;
public int dwPromptFlags;
public IntPtr hwndApp;
public String szPrompt;
}
static private IntPtr NullPtr = ((IntPtr)
((int)(0)));
private const int
CRYPTPROTECT_UI_FORBIDDEN = 0x1;
private const int
CRYPTPROTECT_LOCAL_MACHINE = 0x4;
public enum Store {USE_MACHINE_STORE = 1,
USE_USER_STORE};
private Store store;
public DataProtector() : this
(Store.USE_MACHINE_STORE) {
}
public DataProtector(Store tempStore) {
store = tempStore;
}
public byte[] Encrypt(byte[] plainText,
byte[] optionalEntropy) {
bool retVal = false;
DATA_BLOB plainTextBlob = new
DATA_BLOB();
DATA_BLOB cipherTextBlob = new
DATA_BLOB();
DATA_BLOB entropyBlob = new
DATA_BLOB();
CRYPTPROTECT_PROMPTSTRUCT prompt
= new CRYPTPROTECT_PROMPTSTRUCT();
InitPromptstruct(ref prompt);
int dwFlags;
try {
try {
int bytesSize =
plainText.Length;
plainTextBlob.pbData = Marshal.AllocHGlobal
(bytesSize);
if(IntPtr.Zero ==
plainTextBlob.pbData) {
throw new
Exception("Unable to allocate plaintext buffer.");
}
plainTextBlob.cbData = bytesSize;
Marshal.Copy
(plainText, 0, plainTextBlob.pbData, bytesSize);
}
catch(Exception ex) {
throw new
Exception("Exception marshalling data. " + ex.Message);
}
if
(Store.USE_MACHINE_STORE == store) {
//Using the machine store, should be providing entropy.
dwFlags =
CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDD EN;
//Check to see if
the entropy is null
if(null ==
optionalEntropy) {
//Allocate something
optionalEntropy = new byte[0];
}
try {
int
bytesSize = optionalEntropy.Length;
entropyBlob.pbData = Marshal.AllocHGlobal
(optionalEntropy.Length);;
if
(IntPtr.Zero == entropyBlob.pbData) {
throw new Exception("Unable to allocate entropy
data buffer.");
}
Marshal.Copy(optionalEntropy, 0,
entropyBlob.pbData, bytesSize);
entropyBlob.cbData = bytesSize;
}
catch(Exception
ex) {
throw new
Exception("Exception entropy marshalling data. " +
ex.Message);
}
}
else {
//Using the user store
dwFlags =
CRYPTPROTECT_UI_FORBIDDEN;
}
retVal = CryptProtectData
(ref plainTextBlob, "", ref entropyBlob,
IntPtr.Zero, ref
prompt, dwFlags,
ref
cipherTextBlob);
if(false == retVal) {
throw new
Exception("Encryption failed. " +
GetErrorMessage(Marshal.GetLastWin32Error()));
}
//Free the blob and
entropy.
if(IntPtr.Zero !=
plainTextBlob.pbData) {
Marshal.FreeHGlobal(plainTextBlob.pbData);
}
if(IntPtr.Zero !=
entropyBlob.pbData) {
Marshal.FreeHGlobal(entropyBlob.pbData);
}
}
catch(Exception ex) {
throw new Exception
("Exception encrypting. " + ex.Message);
}
byte[] cipherText = new byte
[cipherTextBlob.cbData];
Marshal.Copy
(cipherTextBlob.pbData, cipherText, 0,
cipherTextBlob.cbData);
Marshal.FreeHGlobal
(cipherTextBlob.pbData);
return cipherText;
}
public byte[] Decrypt(byte[] cipherText,
byte[] optionalEntropy) {
bool retVal = false;
DATA_BLOB plainTextBlob = new
DATA_BLOB();
DATA_BLOB cipherBlob = new
DATA_BLOB();
CRYPTPROTECT_PROMPTSTRUCT prompt
= new
CRYPTPROTECT_PROMPTSTRUCT
();
InitPromptstruct(ref prompt);
try {
try {
int
cipherTextSize = cipherText.Length;
cipherBlob.pbData
= Marshal.AllocHGlobal(cipherTextSize);
if(IntPtr.Zero ==
cipherBlob.pbData) {
throw new
Exception("Unable to allocate cipherText buffer.");
}
cipherBlob.cbData
= cipherTextSize;
Marshal.Copy
(cipherText, 0, cipherBlob.pbData,
cipherBlob.cbData);
}
catch(Exception ex) {
throw new
Exception("Exception marshalling data. " +
ex.Message);
}
DATA_BLOB entropyBlob =
new DATA_BLOB();
int dwFlags;
if
(Store.USE_MACHINE_STORE == store) {
//Using the machine store, should be providing
entropy.
dwFlags =
CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDD
EN;
//Check to see if
the entropy is null
if(null ==
optionalEntropy) {
//Allocate something
optionalEntropy = new byte[0];
}
try {
int
bytesSize = optionalEntropy.Length;
entropyBlob.pbData = Marshal.AllocHGlobal
(bytesSize);
if
(IntPtr.Zero == entropyBlob.pbData) {
throw new Exception("Unable to allocate entropy
buffer.");
}
entropyBlob.cbData = bytesSize;
Marshal.Copy(optionalEntropy, 0,
entropyBlob.pbData,
bytesSize);
}
catch(Exception
ex) {
throw new
Exception("Exception entropy marshalling data. " +
ex.Message);
}
}
else {
//Using the user store
dwFlags =
CRYPTPROTECT_UI_FORBIDDEN;
}
retVal =
CryptUnprotectData(ref cipherBlob, null, ref
entropyBlob,
IntPtr.Zero, ref
prompt, dwFlags,
ref
plainTextBlob);
if(false == retVal) {
throw new
Exception("Decryption failed. " +
GetErrorMessage(Marshal.GetLastWin32Error()));
}
//Free the blob and
entropy.
if(IntPtr.Zero !=
cipherBlob.pbData) {
Marshal.FreeHGlobal(cipherBlob.pbData);
}
if(IntPtr.Zero !=
entropyBlob.pbData) {
Marshal.FreeHGlobal(entropyBlob.pbData);
}
}
catch(Exception ex) {
throw new Exception
("Exception decrypting. " + ex.Message);
}
byte[] plainText = new byte
[plainTextBlob.cbData];
Marshal.Copy
(plainTextBlob.pbData, plainText, 0,
plainTextBlob.cbData);
Marshal.FreeHGlobal
(plainTextBlob.pbData);
return plainText;
}
private void InitPromptstruct(ref
CRYPTPROTECT_PROMPTSTRUCT ps) {
ps.cbSize = Marshal.SizeOf(typeof
(CRYPTPROTECT_PROMPTSTRUCT));
ps.dwPromptFlags = 0;
ps.hwndApp = NullPtr;
ps.szPrompt = null;
}
private unsafe static String
GetErrorMessage(int errorCode) {
int
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS
= 0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM =
0x00001000;
int messageSize = 255;
String lpMsgBuf = "";
int dwFlags =
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
IntPtr ptrlpSource = new IntPtr();
IntPtr prtArguments = new IntPtr
();
int retVal = FormatMessage
(dwFlags, ref ptrlpSource, errorCode, 0,
ref lpMsgBuf,
messageSize,
&prtArguments);
if(0 == retVal) {
throw new Exception
("Failed to format message for error code " +
errorCode + ". ");
}
return lpMsgBuf;
}
}
}[color=blue]
>-----Original Message-----
>The Data Protection API in Windows would help here. I[/color]
remember seeing an[color=blue]
>article about how to do this in a magazine, but cannot[/color]
remember which one.[color=blue]
>
>The DPAPI, would require p/invoke to the Windows API.
>
>"Nicholas Paldino [.NET/C# MVP]"[/color]
<mvp@spam.guard.caspershouse.com> wrote in[color=blue]
>message news:ekQrBsMwDHA.1740@TK2MSFTNGP12.phx.gbl...[color=green]
>> Dave,
>>
>> You can use the classes in the[/color][/color]
System.Security.Cryptography namespace[color=blue]
>to[color=green]
>> encrypt/decrypt a file. However, you run into another[/color][/color]
problem, where will[color=blue][color=green]
>> you store the key? If you store it in the assembly,[/color][/color]
the assembly can be[color=blue][color=green]
>> browsed to find the key and then someone else can use[/color][/color]
it to decrypt your[color=blue][color=green]
>> data.
>>
>> Hope this helps.
>>
>>
>> --
>> - Nicholas Paldino [.NET/C# MVP]
>> -
mvp@spam.guard.caspershouse.com
>>
>> "Dave Bailey" <anonymous@discussions.microsoft.com>[/color][/color]
wrote in message[color=blue][color=green]
>> news:0c8c01c3c0c7$6e7dd0f0$a301280a@phx.gbl...[color=darkred]
>> > I need to store an encrypted connection string in the
>> > web.config file. I have found several examples on[/color][/color][/color]
the Net[color=blue][color=green][color=darkred]
>> > but nothing specific as to how to accomplish task.
>> >
>> > Thanks in advance,
>> >
>> > Dave[/color]
>>
>>[/color]
>
>
>.
>[/color]