Home arrow ASP.NET arrow Page 4 - Cryptographic Objects in C#: Part 1
ASP.NET

Cryptographic Objects in C#: Part 1


In this article, Richard takes us through some of the cryptography tools available in the .NET Framework that provide hashing and encryption of different types of data.

Author Info:
By: Wrox Team
Rating: 5 stars5 stars5 stars5 stars5 stars / 33
February 05, 2003
TABLE OF CONTENTS:
  1. · Cryptographic Objects in C#: Part 1
  2. · Hashing Functions
  3. · Hashing Class
  4. · Using ICryptoTransform Interfaces and Cryptographic Objects
  5. · Conclusion

print this article
SEARCH DEVARTICLES

Cryptographic Objects in C#: Part 1 - Using ICryptoTransform Interfaces and Cryptographic Objects
(Page 4 of 5 )

In the following code we will see how the actual encryption is done. Formerly (in beta 1) we would have defined a class which implemented ICryptoStream to allow us to write to any stream - this could then be custom defined. The authors of the .NET Crypto libraries have simplified this even further in Beta 2 by allowing ICryptoTransform interfaces to be created that represent either encryption or decryption. This contains all the key and IV information.

try
{
  //Here we create the decryption objects but if the key file doesn't
  //exist, automatically throw an exception again
            
outName = fileNameOrTextToEncrypt.Substring(0, fileNameOrTextToEncrypt.Length - 3)+"key";
            
ReadKeyFileContents(ref keyVal, ref IVVal, outName);
ICryptoTransform streamDecrypt = d.CreateDecryptor(keyVal, IVVal);
            
CryptoStream csDecrypt = new CryptoStream(fOut, streamDecrypt, CryptoStreamMode.Write);  
            
  len = 0;
  lenCount = 0;
  byte[] bOutputDecrypt = new byte[4096];
  while (lenCount < fileLength) {
    len = fIn.Read(bContents,0,4096);
              csDecrypt.Write(bContents,0,len);
    lenCount = lenCount + len;
  }
  csDecrypt.FlushFinalBlock();
  csDecrypt.Close();    
}
catch(Exception e)
{
  throw e;
}


Some of the above file handling code might be familiar to .NET aficionados. The CryptoStream object is created and takes as its arguments the ICryptoTransform interface (which is our Decryptor and contains the key and IV that we need). It also needs a valid stream object. In the above code it is a FileStream although this is because we are going to write to a file.

In a later piece of code we use a MemoryStream in the same place to write to memory and retrieve our encrypted output as a byte array.

However, it just needs to be a stream which means that it can be written to any networking stream object too. In the while loop we read from one file and then write to the CryptoStream (effectively in this case another file). The Stream can be written to any number of times, then FlushFinalBlock() is called followed by Close(), which will flush the stream buffer. Close releases all handles (in this case to files).

MemoryStream mStream = new MemoryStream();
mStream.Position = 0;
        
if(!bToBeEncrypted)
{
ICryptoTransform streamDecrypt = d.CreateDecryptor(keyVal, IVVal);
  CryptoStream csEncryptString = new CryptoStream(mStream, streamDecrypt, CryptoStreamMode.Write);
    csEncryptString.Write(Encoding.Default.GetBytes(fileNameOrTextToEncrypt), 0,
             Encoding.Default.GetBytes(fileNameOrTextToEncrypt).Length);

csEncryptString.FlushFinalBlock();
csEncryptString.Close();  
}


As can be seen from the above implementation a MemoryStream can be used in place of a FileStream. This exemplifies the idea that any stream can be used. A MemoryStream is useful in this effect as an area of memory can be written to as a stream and later discarded when the contents are retrieved into an array or string.

private void CreateKeyFile(File f)
{
  string outNameKey = f.FullName.Substring(0, f.FullName.Length - 3)+"key";
  FileStream fKey = new FileStream(outNameKey, FileMode.Create, FileAccess.Write);
  StreamWriter sKey = new StreamWriter(fKey);
  sKey.WriteLine(Convert.ToBase64String(keyAlg.Key()));
  sKey.WriteLine(Convert.ToBase64String(keyAlg.IV()));
  sKey.Flush();
  sKey.Close();
  fKey.Close();
}


After the first encryption is done then the key file is written in the same directory as the plaintext and the cipher text output. The above method is used to write a Base64 encoded version of the key and the IV to a file. This can again be extended to use a key file which contains multiple keys.
I've written this article into a .dll project which can be used generically within a project. The following sample code (ConsoleClient.cs) explains how to use the objects contained therein:

try
{
//First file encryption or decryption
CryptoWrapper.EncryptStringOrFile e = new EncryptStringOrFile(EncryptStringOrFile.KeyEncryptAlgorithm.DES,
                                                            "C:\\temp.enc");
  string temp = e.Encrypt();
  //Then hash passwords ans usernames
CryptoWrapper.HashLoginCredentials h = new HashLoginCredentials(HashLoginCredentials.HashTypeDef.SHA1,
                                                    "username", "password");
  string hash = h.Hash(true);
  //Then encrypt a stream
  CryptoWrapper.EncryptStringOrFile e1 = new EncryptStringOrFile(EncryptStringOrFile.KeyEncryptAlgorithm.DES,
                                                       "EncryptOrDecryptThisText");
  string temp1 = e1.Encrypt();

  Console.WriteLine("filename is: "+temp);
  Console.WriteLine("hash is: "+hash);
  Console.WriteLine("Encrypted text is: "+temp1);
  Console.WriteLine("\r\nPress any key to exit...");
  Console.Read();
  return 0;
}
catch(Exception e)
{
  Console.WriteLine(e.StackTrace);
  return 0;
}


Here is an example of the encrypted output from the above main() method:



In the first line "temp.enc" is passed to the EncryptFileOrString object and then the encrypt method is called which looks for the key file in the respective directory and decrypts the file into "temp.tmp ". It returns the name of the output file is successful.

In the second operation a HashLoginCredentials object is created and it is instructed to use a SHA1 hash, username and password is passed into this constructor and the resultant hash is returned.

In the final operation a DES algorithm is used to encrypt some plaintext. The cipher text is returned to the console in the form of a string. The only prerequisite is for a file called C:\temp.key to exist so that key information can used to encrypt and decrypt plain and cipher text respectively.

A test harness for the .dll has been provided in ASP.NET. After extracting the .zip file, typing http://localhost/CryptoWrapper/login.aspx (assuming you have installed a web server) should present the following screen:



There is a readme.txt file to accompany the test harness which should be read prior to using the page. However, code from the test harness can be easily adapted into an application to allow, amongst other things, logins and password hashing from which can be stored and retrieved from an XML file and also applications that allow files to be uploaded but encrypt them on the server to allow a greater level of security.
blog comments powered by Disqus
ASP.NET ARTICLES

- How Caching Means More Ca-ching, Part 2
- How Caching Means More Ca-ching, Part 1
- Reading a Delimited File Using ASP.Net and V...
- What is .Net and Where is ASP.NET?
- An Object Driven Interface with .Net
- Create Your Own Guestbook In ASP.NET
- HTTP File Download Without User Interaction ...
- Dynamically Using Methods in ASP.NET
- Changing the Page Size Interactively in a Da...
- XML Serialization in ASP.NET
- Using Objects in ASP.NET: Part 1/2
- IE Web Controls in VB.NET
- Class Frameworks in VB .NET
- Cryptographic Objects in C#: Part 1
- Sample Chapter: Pure ASP.Net

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials