Avatar of ClassicCPLus
ClassicCPLus
 asked on

encrypt/decrypt .net 4.0 best practice c#

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

Avatar of undefined
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;
            }
kaufmed

Any particular reason why you're not using the classes found under the System.Security.Cryptography namespace?
ClassicCPLus

ASKER
No particular reason, only this is a legacy application that has been upgraded, I want to use RijndaelManaged
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
ASKER CERTIFIED SOLUTION
ClassicCPLus

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
ClassicCPLus

ASKER
I've requested that this question be closed as follows:

Accepted answer: 0 points for ClassicCPLus's comment #a39714688

for the following reason:

The example I found on Microsoft  works great!
ClassicCPLus

ASKER
See my two previous posts with the solution I am using.
ClassicCPLus

ASKER
I am using this http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2. Is it possible to save the key and vector byte() on the web.config? if so how? an example would be greatly appreciated.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
SOLUTION
btan

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
ClassicCPLus

ASKER
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.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
btan

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.

Pls see this
http://vbcity.com/forums/t/89938.aspx

Also alternatively the use of Rfc2898DeriveBytes
http://www.codeproject.com/Articles/38804/Encryption-and-Decryption-on-the-NET-Framework
ClassicCPLus

ASKER