Link to home
Start Free TrialLog in
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.
Avatar of ClassicCPLus
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;
            }
Avatar of kaufmed
Any particular reason why you're not using the classes found under the System.Security.Cryptography namespace?
No particular reason, only this is a legacy application that has been upgraded, I want to use RijndaelManaged
ASKER CERTIFIED SOLUTION
Avatar of ClassicCPLus
ClassicCPLus

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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!
See my two previous posts with the solution I am using.
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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I am using ASP.NET 4.0 with VS 2010 not ASP.NET 4.0
This application was written in 2.0 and has been upgraded to 4.0
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.

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