In .NET 4.0 what is the safest way to encrypt/decrypt a value I am passing as a query string. What is the best practice, please provide the code (complete class) and the website or book or article, etc showing it is best bractice, you see, I have to proof to our security person we are complying with industry standards.
.NET ProgrammingEncryptionWeb Applications
Last Comment
ClassicCPLus
8/22/2022 - Mon
ClassicCPLus
ASKER
We are using this. However, according to our security guy it is no longer good enough.
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_FORBIDDEN;
//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;
}
I am using ASP.NET 4.0 with VS 2010 not ASP.NET 4.0
ClassicCPLus
ASKER
This application was written in 2.0 and has been upgraded to 4.0
ClassicCPLus
ASKER
Will you send me an example of how to create the key and the vector and then how to convert it to a format I can save on the web.config, you see, I created it using RijndaelManaged.GenerateKey() and RijndaelManaged.GenerateIV() then converted to a string and saved it on the web.config . However when I retrieve the value from the web.config and then use Encoding.ASCII.GetBytes("Key") to pass the value to RijndaelManged.Key I get error: "Specified key is not a valid size for this algorithm". I hope this is clear, I really appreciate your help with this, I am stuck.
The RijndaelManaged algorithm supports key lengths of 128, 192, or 256 bits. Your key one should be one of these sizes, default is 128 bits. E.g.
The string "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912" when base64-decoded yields 48 bytes (384 bits). RijndaelManaged supports 128, 192 and 256 bit keys.
A valid 128-bit key is new byte[]{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } or if you need to get it from base64 : Convert.FromBase64String("AAECAwQFBgcICQoLDA0ODw==").
The default blocksize is 128 bits, so the same byte-array will work as the IV.
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(bytes
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
{//Using the machine store, should be providing entropy.
dwFlags = CRYPTPROTECT_LOCAL_MACHINE
//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(optio
if(IntPtr.Zero == entropyBlob.pbData)
{
throw new Exception("Unable to allocate entropy data buffer.");
}
Marshal.Copy(optionalEntro
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.Ge
}
//Free the blob and entropy.
if(IntPtr.Zero != plainTextBlob.pbData)
{
Marshal.FreeHGlobal(plainT
}
if(IntPtr.Zero != entropyBlob.pbData)
{
Marshal.FreeHGlobal(entrop
}
}
catch(Exception ex)
{
throw new Exception("Exception encrypting. " + ex.Message);
}
byte[] cipherText = new byte[cipherTextBlob.cbData
Marshal.Copy(cipherTextBlo
Marshal.FreeHGlobal(cipher
return cipherText;
}