2009/04/04

Tips: Clean Session/Cache (4/21/2009 updated)

Clean Session:
Session.Clear();
Totally remove the Session:
Session.Abandon();
Clean Cache:
HttpRuntime.Close();
Note: Be careful when using this way to clear the cache (See here). I found a better way to do the same thing from here.
List cacheKeys = new List();
IDictionaryEnumerator cacheEnum = Cache.GetEnumerator();
while (cacheEnum.MoveNext())
{
cacheKeys.Add(cacheEnum.Key.ToString());
}
foreach (string cacheKey in cacheKeys)
{
Cache.Remove(cacheKey);
}

Reference: What is the best way to end session?

2009/04/03

RSA String Encryption/Decryption

Same with the TripleDES, here is what I use to encrypt/decrypt string (not a good idea to encrypt files). Here is the encryption:
public byte[] RSAEncryptString(string data, string xmlKeyString)
{
  try
  {
    RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
    oRSA.FromXmlString(xmlKeyString);
    return oRSA.Encrypt(Encoding.UTF8.GetBytes(data), false);
  }
  catch (CryptographicException cex)
  {
    throw cex;
  }
}
Here is the decryption:
public string RSADecryptString(byte[] data, string xmlKeyString)
{
  try
  {
    RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
    oRSA.FromXmlString(xmlKeyString);
    return Encoding.UTF8.GetString(oRSA.Decrypt(data, false));
  }
  catch (CryptographicException cex)
  {
    throw cex;
  }
}
It's better to use RSA to generate the public/private key pair:
public List<string> RSAKeypairGenerator()
{
  List<string> lstResult = new List<string>();
  RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
  //public key
  lstResult.Add(oRSA.ToXmlString(false));
  //private key
  lstResult.Add(oRSA.ToXmlString(true));
  oRSA.Clear();
  return lstResult;
}

2009/04/01

TripleDES File Encryption/Decryption (6/13/2011 updated)

Here is how I encrypt/decrypt file by using the TripleDES. The inputFilename (and outputFilename) better includes the full path, ex. "C:\Temp\123.pdf".
public string TripleDESforFile(string inputFilename, string outputFilename, string key, string IV, bool toEncrypt)
{
  try
  {
    using (FileStream fsInput = new FileStream(inputFilename, FileMode.Open, FileAccess.Read))
    {
      using (FileStream fsOutput = new FileStream(outputFilename, FileMode.Create, FileAccess.Write))
      {
        PasswordDeriveBytes oPasswordDeriveBytes = new PasswordDeriveBytes(key, Encoding.UTF8.GetBytes(FormatStringLength(IV, 8, '9')));
        TripleDESCryptoServiceProvider oTDES = new TripleDESCryptoServiceProvider();
        oTDES.Mode = CipherMode.CBC;
        oTDES.Padding = PaddingMode.PKCS7;
        //Create the key and set it to the Key property of the TripleDESCryptoServiceProvider object.
        oTDES.Key = oPasswordDeriveBytes.GetBytes(24);  //must 24 bytes
        oTDES.IV = oPasswordDeriveBytes.GetBytes(8);  //must 8 bytes

        // Now create a crypto stream through which we are going
        // to be pumping data.
        // The fsOutput is going to be receiving the encrypted bytes.
        CryptoStream oCryptoStream = toEncrypt ?
          oCryptoStream = new CryptoStream(fsOutput, oTDES.CreateEncryptor(), CryptoStreamMode.Write) :
          oCryptoStream = new CryptoStream(fsOutput, oTDES.CreateDecryptor(), CryptoStreamMode.Write);

        // Now will will initialize a buffer and will be processing the input file in chunks.
        // This is done to avoid reading the whole file (which can be huge) into memory.
        int bufferLen = 4096;
        byte[] buffer = new byte[bufferLen];
        int bytesRead;

        do
        {
          // read a chunk of data from the input file
          bytesRead = fsInput.Read(buffer, 0, bufferLen);
          // encrypt it
          oCryptoStream.Write(buffer, 0, bytesRead);
        }
        while (bytesRead != 0);

        oCryptoStream.Close();
        oTDES.Clear();
      }
    }
    return "Success";
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
  catch (IOException ioe)
  {
    return ioe.Message;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
}

6/13/2011 updated:
Use the PasswordDeriveBytes class to generate the Key and IV for the 3DES.

TripleDES String Encryption/Decryption (6/12/2011 updated)

Here is how I encrypt/decrypt string by using the TripleDES.
public string TripleDESforString(string rawString, string key, string IV, bool toEncrypt)
{
  try
  {
    //Create a PasswordDeriveBytes object and then create a TripleDES key from the password and salt.
    PasswordDeriveBytes oPasswordDeriveBytes = new PasswordDeriveBytes(key, Encoding.UTF8.GetBytes(FormatStringLength(IV, 8, '9')));
    TripleDESCryptoServiceProvider oTDES = new TripleDESCryptoServiceProvider();
    oTDES.Padding = PaddingMode.PKCS7;
    oTDES.Mode = CipherMode.CBC;
    //Create the key and set it to the Key property of the TripleDESCryptoServiceProvider object.
    //oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
    oTDES.Key = oPasswordDeriveBytes.GetBytes(24);
    oTDES.IV = oPasswordDeriveBytes.GetBytes(8);

    byte[] data;
    byte[] result;
    if (toEncrypt)
    {
      data = Encoding.UTF8.GetBytes(rawString);
      result = oTDES.CreateEncryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Convert.ToBase64String(result);
    }
    else
    {
      data = Convert.FromBase64String(rawString);
      result = oTDES.CreateDecryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Encoding.UTF8.GetString(result);
    }
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
}
The TripleDES class will throw an Exception if you assign it with the weak key. The easy way to prevent this situation is to use the key that generated by the TripleDES itself.
public List<byte[]> TripleDESKeyGenerator()
{
  List<byte[]> lstResult = new List<byte[]>();
  TripleDES oTDES = TripleDESCryptoServiceProvider.Create();
  oTDES.GenerateKey();
  oTDES.GenerateIV();
  lstResult.Add(oTDES.Key);
  lstResult.Add(oTDES.IV);
  oTDES.Clear();
  return lstResult;
}


2/5/2010 updated:
Put on the FormatStringLength() method.
public static string FormatStringLength(string input, int requiredLength, char padding)
{
  if (input.Length < requiredLength)
    input = input.PadRight(requiredLength, padding);
  else if (input.Length > requiredLength)
    input = input.Substring(0, requiredLength);

  return input;
}

6/12/2011 updated:
Replaced the following line
oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
with
oTDES.Key = oPasswordDeriveBytes.GetBytes(24);

Remove DBNull

If you are getting data from SQL server, it always has a chance that you will get the Null in your table cell. But the meaning of "Null" in database is different than it in the .Net. So how to remove the Null from the resultset getting from the database?
1.Use IsNull() function in your stored procedures.
Select Name, IsNull(Age, 18) From Members
2.Use the following simple method
public DataTable RemoveDBNull(DataTable dt)
{
  for (int i = 0; i < dt.Rows.Count; i++)
  {
    for (int j = 0; j < dt.Columns.Count; j++)
    {
      if (dt.Rows[i][j] == DBNull.Value)
        dt.Rows[i][j] = 0;
    }
  }
  return dt;
}