Using .NET Encryption Classes


The .NET framework includes a rich set of classes for performing cryptographic operations. You can access any of these classes within an ASP.NET page.

In several situations, you need to use these classes in an ASP.NET application. For example you can use these classes to encrypt sensitive information, such as credit card numbers and legal documents, before you store the information in a database table or the file system. You also can use these classes to automatically add digital signatures to documents.

In the following sections, you learn how to use the cryptography classes to generate hash codes, encrypt data by using both symmetric and asymmetric cryptographic algorithms, and create digital signatures.

NOTE

Many of the cryptographic classes in the .NET framework are managed wrappers for the Windows Cryptographic Service Providers (CSPs). To use a particular cryptographic class, the proper CSP must be installed.


Using Hash Algorithms

A hash algorithm generates a fixed-length hash value that uniquely represents the contents of an arbitrary length string. Identical strings generate the same hash value. Strings that differ in the smallest respect generate different hash values.

Imagine that you have a file that contains the complete text of the Declaration of Independence. You can use a hash algorithm to generate a string of 16 characters that represent the contents of this file. If you change a single letter in the file, the hash algorithm would generate a different hash value.

Hash values are useful for detecting changes in a file. They enable you to take a snapshot of the state of a file at any point of time. If you want to know whether a file has been changed on the hard drive, you can compare the file's current hash value to its previous hash value.

Hash values can be used to protect data integrity. For example, the Forms authentication module uses hash values to detect changes in the cookie Authentication Tickets that it issues.

The classes in the .NET framework support the following hash algorithms:

  • MD5 This hash algorithm generates a 128-bit hash value. (To learn more about it, see RFC 1321 at www.w3.org.) This hash algorithm is implemented by the MD5CryptoServiceProvider class.

  • SHA1 The original Secure Hash Algorithm generates a 160-bit hash value. It is implemented by the SHA1CryptoServiceProvider and SHA1Managed classes.

  • SHA256 The Secure Hash Algorithm 256 generates a 256-bit hash value. It is implemented by the SHA256CryptoServiceProvider and SHA256Managed classes.

  • SHA384 The Secure Hash Algorithm 384 generates a 384-bit hash value. It is implemented by the SHA384CryptoServiceProvider and SHA384Managed classes.

  • SHA512 The Secure Hash Algorithm 512 generates a 512-bit hash value. It is implemented by the SHA512CryptoServiceProvider and SHA512Managed classes.

The MD5 hash algorithm is the fastest but the least secure. Each SHA algorithm is progressively more secure but requires more computation.

NOTE

The System.Security.Cryptography namespace includes two classes that support keyed hashed algorithms: HMACSHA1 and MACTripleDES . These classes are particularly useful for generating message authentication codes (MACs).


You can use any of these classes to compute a hash value by calling the ComputeHash method. This method accepts a byte array that represents the data to be hashed and returns a byte array that represents the hash value. For example, the ASP.NET page in Listing 21.2 returns a hash value by using the MD5 hash algorithm (see Figure 21.4).

Listing 21.2 Hash.aspx
 <%@ Import Namespace="System.Security.Cryptography" %> <Script Runat="Server"> Function Convert2ByteArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrChar As Char()   arrChar = strInput.ToCharArray()   Dim arrByte( arrChar.Length - 1 ) As Byte   For intCounter = 0 To arrByte.Length - 1     arrByte( intCounter ) = Convert.ToByte( arrChar( intCounter ) )   Next   Return arrByte End Function Sub Button_Click( s AS Object, e As EventArgs )   Dim arrHashInput As Byte()   Dim arrHashOutput As Byte()   Dim objMD5 As MD5CryptoServiceProvider   objMD5 = New MD5CryptoServiceProvider   arrHashInput = Convert2ByteArray( txtInput.Text )   arrHashOutput = objMD5.ComputeHash( arrHashInput )   lblOutput.Text = BitConverter.ToString( arrHashOutput ) End Sub </Script> <html> <head><title>Hash.aspx</title></head> <body> <form Runat="Server"> <h2>Generate MD5 Hash</h2> <b>Enter text to hash:</b> <br> <asp:TextBox   id="txtInput"   TextMode="Multiline"   Columns="50"   Rows="10"   Runat="Server" /> <p> <asp:Button   Text="Compute Hash!"   OnClick="Button_Click"   Runat="Server" /> <p> <b>Hash value:</b> <br> <asp:Label   ID="lblOutput"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

Figure 21.4. Computing a hash value.

graphics/21fig04.jpg

The page in Listing 21.2 displays a multiline TextBox control. If you enter text into it and click the submit button, the hash value for the text is displayed. Notice that even a single character difference generates a different hash value.

You cannot pass a string directly to the ComputeHash method of any of the Hash classes. In Listing 21.2, the string is converted to a byte array with the Convert2ByteArray function before being passed to the ComputeHash method. The byte array returned by ComputeHash is converted back to a string with the BitConverter class.

Using Symmetric Encryption Algorithms

When you think of encryption, you typically think of symmetric encryption algorithms. When you encrypt a message with a symmetric encryption algorithm, both the sender and recipient of the message must share the same decryption key.

The classes in the .NET framework support the following symmetric encryption algorithms:

  • DES The United States Data Encryption Standard. This algorithm is implemented by the DESCryptoServiceProvider class.

  • Triple DES DES encryption applied three times in a row with different session encryption keys. This algorithm is implemented by the TripleDESCryptoServiceProvider class.

  • RC2 The RC2 Block Cipher. This algorithm is implemented by the RC2CryptoServiceProvider class.

  • Rijndael The algorithm used for the Advanced Encryption Standard (AES). This algorithm is implemented by the RijndaelManaged class.

You can use any of these encryption algorithms in your ASP.NET pages. For example, you can encrypt information that users enter into an HTML form and send the information in an email, store the information on the file system, or add the information to a database table.

For this next example, you use the DESCryptoServiceProvider class to encrypt form data and store the encrypted data in a file. You need to create two ASP.NET pages: SymmetricWrite.aspx and SymmetricRead.aspx . The SymmetricWrite.aspx page, contained in Listing 21.3, will encrypt and write the data to a file, and the SymmetricRead.aspx page will read and decrypt the data from the file.

Listing 21.3 SymmetricWrite.aspx
 <%@ Import Namespace="System.IO" %> <%@ Import Namespace="System.Security.Cryptography" %> <Script Runat="Server"> CONST DESKey As String = "ABCDEFGH" CONST DESIV As String = "HGFEDCBA" Function Convert2ByteArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrChar As Char()   arrChar = strInput.ToCharArray()   Dim arrByte( arrChar.Length - 1 ) As Byte   For intCounter = 0 To arrByte.Length - 1     arrByte( intCounter ) = Convert.ToByte( arrChar( intCounter ) )   Next   Return arrByte End Function Sub Button_Click( s As Object, e As EventArgs )   Dim arrDESKey As Byte()   Dim arrDESIV AS Byte()   Dim arrInput As Byte()   Dim objFileStream As FileStream   Dim objDES As DESCryptoServiceProvider   Dim objEncryptor As ICryptoTransform   Dim objCryptoStream As CryptoStream   arrDESKey = Convert2ByteArray( DESKey )   arrDESIV = Convert2ByteArray( DESIV )   arrInput = Convert2ByteArray( txtInput.Text )   objDES = New DESCryptoServiceProvider()   objEncryptor = objDES.CreateEncryptor( arrDESKey, arrDESIV )   objFileStream = New FileStream( _     MapPath( "secret.txt" ), _     FileMode.Create, _     FileAccess.Write )   objCryptoStream = New CryptoStream( _     objFileStream, _     objEncryptor, _     CryptoStreamMode.Write )   objCryptoStream.Write( arrInput, 0, arrInput.Length )   objCryptoStream.Close() End Sub </Script> <html> <head><title>SymmetricWrite.aspx</title></head> <body> <form Runat="Server"> <h2>DES Encryption</h2> <b>Enter text to encrypt:</b> <br> <asp:TextBox   id="txtInput"   TextMode="Multiline"   Columns="50"   Rows="10"   Runat="Server" /> <p> <asp:Button   Text="Encrypt!"   OnClick="Button_Click"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

The page in Listing 21.3 displays a form with a single TextBox control (see Figure 21.5). If you enter text into it and click the submit button, the form data is encrypted using the DES encryption algorithm and saved to a file named secret.txt.

Figure 21.5. Encrypting a file.

graphics/21fig05.jpg

Notice the two constants named DESKey and DESIV defined at the top of the file. When you encrypt data with DESCryptoServiceProvider , you must supply both a secret key and an initialization vector. You need to use these two constants to decrypt the file after you create it.

In Listing 21.3, the secret key is assigned the value ABCDEFGH , and the initialization vector is assigned the value HGFEDCBA . You should think of these values as the secret passwords to the file. You can assign any eight-character string to these constants.

You can decrypt the contents of the secret.txt file by using the ASP.NET page in Listing 21.4 (see Figure 21.6).

Listing 21.4 SymmetricRead.aspx
 <%@ Import Namespace="System.IO" %> <%@ Import Namespace="System.Security.Cryptography" %> <Script Runat="Server"> CONST DESKey As String = "ABCDEFGH" CONST DESIV As String = "HGFEDCBA" Sub Page_load   DESDecrypt End Sub Function Convert2ByteArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrChar As Char()   arrChar = strInput.ToCh arArray()   Dim arrByte( arrChar.Length - 1 ) As Byte   For intCounter = 0 To arrChar.Length - 1     arrByte( intCounter ) = Convert.ToByte( arrChar( intCounter ) )   Next   Return arrByte End Function Sub DESDecrypt   Dim arrDESKey As Byte()   Dim arrDESIV As Byte()   Dim objFileStream As FileStream   Dim objDES As DESCryptoServiceProvider   Dim objDecryptor As ICryptoTransform   Dim objCryptoStream As CryptoStream   arrDESKey = Convert2ByteArray( DESKey )   arrDESIV = Convert2ByteArray( DESIV )   objDES = New DESCryptoServiceProvider   objDecryptor = objDES.CreateDecryptor( arrDESKey, arrDESIV )   objFileStream = New FileStream( _     MapPath( "secret.txt" ), _     FileMode.Open, _     FileAccess.Read )   objCryptoStream = New CryptoStream( _     objFileStream, _     objDecryptor, _     CryptoStreamMode.Read )    lblMessage.Text = New StreamReader( objCryptoStream ).ReadToEnd()   objFileStream.Close End Sub </Script> <html> <head><title>SymmetricRead.aspx</title></head> <body> <h2>DES Decryption</h2> <b>Decrypted Text:</b> <p> <asp:Label   ID="lblMessage"   Runat="Server" /> </body> </html> 

The C# version of this code can be found on the CD-ROM.

Figure 21.6. Decrypting a file.

graphics/21fig06.jpg

The page in Listing 21.4 reads, decrypts, and displays the contents of the secret.txt file in the DESDecrypt subroutine. Notice that the DESKey and DESIV constants are defined at the top of the page. The values of these constants in this page must match the values of these constants in the SymmetricWrite.aspx page.

Using Asymmetric Encryption

When you use a symmetric encryption algorithm, both the sender and recipient of a message must share a common decryption key. You use the same secret key to encrypt a message as the key that you use to decrypt the message.

When you use an asymmetric encryption algorithm, on the other hand, the key used to encrypt a message is distinct from the key used to decrypt the message. Asymmetric encryption algorithms use a key pair. If you encrypt a message with one key, you need the other key to decrypt the message.

Asymmetric encryption algorithms often are used to create digital signatures. Typically, one key is made public, and the other key is kept private. If you encrypt a message with your private key, it can be decrypted only with your public key. If you send another user a message encrypted with your private key, that user can verify that you sent the message by decrypting it with your public key.

NOTE

Asymmetric algorithms are often referred to as public key algorithms .


When used with a hash algorithm, an asymmetric algorithm can detect whether a message has been altered. For example, if George needs to send Jane a message, and George and Jane need to ensure that the message has not been altered in transit, the two of them can do the following:

  1. George computes the hash value of the message.

  2. George encrypts the hash value with his private key.

  3. George sends the message and encrypted hash value to Jane.

  4. Jane decrypts the hash value received from George.

  5. Jane computes the hash value of the message herself.

  6. If the two hash values match, Jane knows that the message has not been modified.

The classes in the .NET framework support the following two asymmetric algorithms:

  • DSA The Digital Signature Algorithm (the digital authentication standard of the United States government). This algorithm is implemented by the DSACryptoServiceProvider class.

  • RSA This algorithm is implemented by the RSACryptoServiceProvider class.

Both algorithms implement the AsymmetricAlgorithm class, so they share many of the same methods and properties. If you create an instance of either class, the private and public keys are automatically generated.

You can access the public or private key by using either the ToXmlString or ExportParameters method. The ToXmlString method represents the public and private keys with an XML string.

The following sample statements create an instance of the DSACryptoServiceProvider class and display the private and public keys:

 
 Dim objDSA As New DSACryptoServiceProvider() Response.Write( "<h2>Private Key:</h2>" ) Response.Write( Server.HTMLEncode( objDSA.ToXmlString( True ) ) ) Response.Write( "<h2>Public Key:</h2>" ) Response.Write( Server.HTMLEncode( objDSA.ToXmlString( False ) ) ) 

Notice that you use the ToXmlString method to display both the private and public keys. You pass the value True to display the private key and the value False to display the public key.

The preceding statements generate output similar to the following:

 
  Private Key:  <DSAKeyValue><P>1AYChM6ITZ1sFQDtDd8rfDNAoeWdIttEpgY53xArTjl1RrZ7LD887IQFRmY CqCjgA0EoToR8elnIbAsr+IGN9h4dRnbKaCk/LupXj1bxJqQbMlqXyfLehxeshRCgajFqAOmMW6 SSlNNdJU8DY8gzPUzSar57UhpbDur1p2MHwlc=</P><Q>5RdZjO/s6pJMQEOnzThKX0/EJp8=</ Q><G>sQNgfhRtZ5GGufpdPgb5zYAP0go4egcNhGibQbIV4OBgqP2jiBLURjnxSHNs5GKbvUGT2t 5Sr2DP8+704Tv+osjNtOsG324Txgdx3Li0wsqguyBu2stlIPI2FxPuTcasLqPmFuWhBHexFT2lg 4w4eVCVH1jlaCZ7lmrI1ux2w2c=</G><Y>FlAgexkYEnPIM06dnGmE5s/mj/7M9V1ohQY+ZH80d LTOWCobBt7T16ToR0dUpcIHDrn7kha5Bj4YnT6pjAr55VtclBu3td8m6M3Ymm8MqLQXTVj9aWem nrHVX+/hMNXOnBGsaf/Lrvjw37TERKocTzJcV9Jv2tsaklC9nQeSx3I=</Y><J>7O1xQHFufGn5 X592ZJ90kuRA/RzxZltsiULtfuNaBu95uNaAYHKOajkBJQP8/U4jzoYvPOTYw9Z37r8BLt8Vt8Q p64IkmlqHMwlFVZhYU/XNwuXfrSdUPxwl6s+eZHe4GKr4H1vz49wTaGvq</J><Seed>b3M+ieba mm7xgDEZmUJ2QNB1elg=</Seed><PgenCounter>ARM=</PgenCounter><X>iJMgNkrX+Wj4pV eSc1VPV2fOBPg=</X></DSAKeyValue>  Public Key:  <DSAKeyValue><P>1AYChM6ITZ1sFQDtDd8rfDNAoeWdIttEpgY53xArTjl1RrZ7LD887IQFRmY CqCjgA0EoToR8elnIbAsr+IGN9h4dRnbKaCk/LupXj1bxJqQbMlqXyfLehxeshRCgajFqAOmMW6 SSlNNdJU8DY8gzPUzSar57UhpbDur1p2MHwlc=</P><Q>5RdZjO/s6pJMQEOnzThKX0/EJp8=</ Q><G>sQNgfhRtZ5GGufpdPgb5zYAP0go4egcNhGibQbIV4OBgqP2jiBLURjnxSHNs5GKbvUGT2t 5Sr2DP8+704Tv+osjNtOsG324Txgdx3Li0wsqguyBu2stlIPI2FxPuTcasLqPmFuWhBHexFT2lg 4w4eVCVH1jlaCZ7lmrI1ux2w2c=</G><Y>FlAgexkYEnPIM06dnGmE5s/mj/7M9V1ohQY+ZH80d LTOWCobBt7T16ToR0dUpcIHDrn7kha5Bj4YnT6pjAr55VtclBu3td8m6M3Ymm8MqLQXTVj9aWem nrHVX+/hMNXOnBGsaf/Lrvjw37TERKocTzJcV9Jv2tsaklC9nQeSx3I=</Y><J>7O1xQHFufGn5 X592ZJ90kuRA/RzxZltsiULtfuNaBu95uNaAYHKOajkBJQP8/U4jzoYvPOTYw9Z37r8BLt8Vt8Q p64IkmlqHMwlFVZhYU/XNwuXfrSdUPxwl6s+eZHe4GKr4H1vz49wTaGvq</J><Seed>b3M+ieba mm7xgDEZmUJ2QNB1elg=</Seed><PgenCounter>ARM=</PgenCounter></DSAKeyValue> 

If you look closely at the private and public keys, you notice that they differ in a final <X> element, which represents the private key.

You can use the SignData method to generate a digital signature for a message. This method accepts one parameter: a byte array representing the message to be signed. The SignHash method returns a byte array that represents the digital signature for the message.

The VerifyData method performs the opposite operation. You can use this method to verify that a message matches its digital signature. It accepts two parameters: a byte array representing the data to verify and a byte array that represents the digital signature. VerifyData returns the value True when the message matches the signature and False otherwise .

The page in Listing 21.5, for example, generates a digital signature for any text that you enter into an HTML form (see Figure 21.7).

Listing 21.5 AsymmetricWrite.aspx
 <%@ Import Namespace="System.Security.Cryptography" %> <Script Runat="Server"> Function Convert2ByteArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrChar As Char()   arrChar = strInput.ToCharArray()   Dim arrByte( arrChar.Length - 1 ) As Byte   For intCounter = 0 To arrByte.Length - 1     arrByte( intCounter ) = Convert.ToByte( arrChar( intCounter ) )   Next   Return arrByte End Function Sub Button_Click( s As Object, e As EventArgs )   Dim arrInput As Byte()   Dim objDSA As DSACryptoServiceProvider   Dim strPublicKey As String   Dim arrDigitalSignature As Byte()   arrInput = Convert2ByteArray( txtInput.Text )   objDSA = New DSACryptoServiceProvider()   strPublicKey = objDSA.ToXMLString( False )   arrDigitalSignature = objDSA.SignData( arrInput )   txtSignature.Text = BitConverter.ToString( arrDigitalSignature )   txtPublicKey.Text = strPublicKey End Sub </Script> <html> <head><title>AsymmetricWrite.aspx</title></head> <body> <H2>Create Digital Signature</h2> <form Runat="Server"> <asp:TextBox   ID="txtInput"   TextMode="Multiline"   Columns="60"   Rows="3"   Runat="Server" /> <p> <asp:Button   Text="Create Signature!"    OnClick="Button_Click"   Runat="Server" /> <p> Digital Signature: <br> <asp:TextBox   ID="txtSignature"   TextMode="Multiline"   Columns="60"   Rows="4"   Runat="Server" /> <p> Public Key: <br> <asp:TextBox   ID="txtPublicKey"   TextMode="Multiline"   Columns="60"   Rows="10"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

Figure 21.7. Generating a digital signature.

graphics/21fig07.jpg

When you enter text into the TextBox control in Listing 21.5 and submit the form, the Button_Click subroutine generates a digital signature by using RSACryptoServiceProvider . The Button_Click subroutine displays the digital signature and the public key associated with the digital signature in two TextBox controls.

The page in Listing 21.6 performs the opposite operation. This page uses the VerifyData method to verify that a message matches a digital signature associated with a particular public key (see Figure 21.8).

Listing 21.6 AsymmetricRead.aspx
 <%@ Import Namespace="System.Globalization" %> <%@ Import Namespace="System.Security.Cryptography" %> <Script Runat="Server"> Function Convert2ByteArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrChar As Char()   arrChar = strInput.ToCharArray()   Dim arrByte( arrChar.Length - 1 ) As Byte   For intCounter = 0 To arrByte.Length - 1     arrByte( intCounter ) = Convert.ToByte( arrChar( intCounter ) )   Next   Return arrByte End Function Function ConvertHexArray( strInput As String ) As Byte()   Dim intCounter As Integer   Dim arrString As String()   arrString = strInput.Split( New Char() { "-" } )   Dim arrByte( arrString.Length - 1 ) As Byte   For intCounter = 0 To arrByte.Length - 1     arrByte( intCounter ) = Byte.Parse( arrString( intCounter ), NumberStyles.HexNumber )   Next   Return arrByte End Function Sub Button_Click( s As Object, e As EventArgs )   Dim arrInput As Byte()   Dim objDSA As DSACryptoServiceProvider   Dim strPublicKey As String   Dim arrDigitalSignature As Byte()   arrInput = Convert2ByteArray( txtInput.Text )   arrDigitalSignature = ConvertHexArray( txtSignature.Text )   objDSA = New DSACryptoServiceProvider()   objDSA.FromXMLString( txtPublicKey.Text )   lblVerify.Text = objDSA.VerifyData( arrInput, arrDigitalSignature ) End Sub </Script> <html> <head><title>AsymmetricRead.aspx</title></head> <body> <H2>Verify Digital Signature</h2> <form Runat="Server"> Message: <br> <asp:TextBox   ID="txtInput"   TextMode="Multiline"   Columns="60"   Rows="3"   Runat="Server" /> <p> Digital Signature: <br> <asp:TextBox   ID="txtSignature"   TextMode="Multiline"   Columns="60"   Rows="4"   Runat="Server" /> <p> Public Key: <br> <asp:TextBox   ID="txtPublicKey"   TextMode="Multiline"   Columns="60"   Rows="10"   Runat="Server" /> <p> <asp:Button   Text="Verify Signature!"   OnClick="Button_Click"   Runat="Server" /> <p> Verified? <br> <asp:Label   ID="lblVerify"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

Figure 21.8. Verifying a digital signature.

graphics/21fig08.jpg

The page in Listing 21.6 displays a form with three TextBox controls: one for a message, one for a digital signature, and one for a public key. If you enter this information and click the verify button, the page returns the value True if the message can be verified and the value False otherwise.



ASP.NET Unleashed
ASP.NET 4 Unleashed
ISBN: 0672331128
EAN: 2147483647
Year: 2003
Pages: 263

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net