Code to Write Log files in C#

dotnetlogo
Following method can be used to write errors into a log file through an application.

using System.IO;
public void WriteLogLine(string sCallerName, string sLogFolder,
long lCallerInstance, string sLogLine)
{
lock(this)
{
string sFileName;
sFileName = String.Format("{0}_{1:yyyy.MM.dd}_{2:00}.log",
sCallerName, DateTime.Now, lCallerInstance);
StreamWriter swServerLog =
new StreamWriter(sLogFolder + sFileName, true);
swServerLog.WriteLine(
String.Format("[{0:T}] {1}", DateTime.Now, sLogLine));
swServerLog.Close();
}
}

Salting the Password in C#

dotnetlogo
Hashed passwords provide much better security than storing passwords in the database as simple text. They are, however, potentially vulnerable to a dictionary attack. In a dictionary attack, the attacker attempts to guess passwords by using software to iteratively hash all words in a large dictionary and compare the generated hashes to the stored hash values.

You can help prevent dictionary attacks by requiring the end users to define passwords that are not common words and that contain some numbers or other nonalphanumeric characters.

In addition, you can add a random set of bytes at the beginning or end of the password before hashing it. This random set of bytes is called a salt. You then store this salt value in the table along with the password.

There are many ways to generate a salt value. One way is to generate a globally unique ID, or GUID, as follows.

public static String ComputeSalt()
{
System.Guid GuidValue = System.Guid.NewGuid();
return GuidValue.ToString();
}

This code can also be included in your utility component so it can be reused.

By using both the hash and the salt, you can minimize the possibility of an unauthorized user accessing your application.

Hashing the Password in C#

dotnetlogo

Every application uses username and password to provide security to the systems. The way an application handles the storage of password defines the level of security provided by the application.

The password should not be stored in the database as a string. Rather, it should be converted to an unrecognizable value that is unique for any defined password. This value is called a hash. Hashing algorithms are defined so that any string that is hashed to a unique value will always be hashed to that unique value.

When an end user defines a password, the password should be hashed to a unique value, and that unique value should be stored in the database. When the end user logs in with the password, the password can be hashed again using the same algorithm. The resulting value can be compared with the hashed value stored in the database to validate the login.

Hashed values cannot be “unhashed,” so there is no way to get the original password back from the hashed value. This provides an additional level of security, because if someone obtains hashed passwords from the database, they cannot be converted back to the original passwords. A side effect of this is that if an end user forgets the password, a new password would need to be assigned.

The System.Security.Cryptography library in the .NET Framework provides a set of classes that assist with hashing. Two primary hashing schemes are provided in this library:

  • MD5: The Message Digest 5 (MD5) hash digest uses an MD5 algorithm to hash a value, such as an end user password. This algorithm provides better performance than SHA1.
  • SHA1: The Secure Hash Algorithm-1 (SHA1) hash digest uses a SHA1 algorithm to hash a value, such as an end user password. This algorithm provides better security than MD5.

A password such as “password” will have a hash that looks something like W6ph5Mm5Pz8GgiULbPgzG37mj9g=.

The following code uses the SHA1 algorithm to hash a password:

using System.Security.Cryptography;
public static String ComputeHash(string textToHash)
{
SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider();
byte[] byteValue = System.Text.Encoding.UTF8.GetBytes(textToHash);
byte[] byteHash = SHA1.ComputeHash(byteValue);
SHA1.Clear();
return Convert.ToBase64String(byteHash);
}

You can put this code in a utility component and reuse it in every application that needs to store a password or other secure information.

But hashing a password does not protect the application from a dictionary attack. For further security, salt the password as well.