AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=784&pId=-1
Password-Protecting Sensitive InfoPath Form Fields
page
by S.Y.M. Wong-A-Ton
Feedback
Average Rating: 
Views (Total / Last 10 Days): 38089/ 60

Introduction

Microsoft Office InfoPath 2003 is based on XML technology.  All data within InfoPath forms, including sensitive data, is saved in clear text and remains readable to anyone who can access the form’s data.  Adding password fields to a form would therefore expose any passwords entered and saved along with the form's data.

This article builds on the concept of encrypting and decrypting data when saving an InfoPath form.  This concept was first discussed in an MSDN article called "Extending the Save Functionality in InfoPath 2003".  This article assumes that you have adequate familiarity with Microsoft InfoPath 2003 and Visual C# .NET.

Software Requirements

·         Microsoft Office InfoPath 2003 Service Pack 1

·         Microsoft Visual Studio .NET 2003

·         Microsoft InfoPath 2003 Toolkit for Visual Studio .NET

Security Concepts

The solution outlined in this article is based on three security concepts: authentication, privacy, and integrity.

Authentication

Authentication is the process of determining the identity of a person or entity.  There are three general factors that can be used for authentication:

1.      Something a person knows

2.      Something a person has

3.      Something a person is

Something a person knows can be a password, PIN, or mother’s maiden name.  Something a person has can be a key, swipe card, or badge.  Biometrics such as fingerprint and iris scans can be used to prove something a person is.  Strong authentication contains two out of these three methods.

Privacy

Privacy is the act of keeping data undisclosed to third parties unless authorized.  Privacy protects sensitive information such as personal information.

Integrity

Integrity provides the assurance that data has not been altered in an unauthorized way.  One example is when a user sends a request to her online bank account to pay her $24.56 water utility bill.  This user needs to be sure that the integrity of that transaction was not altered during transmission, so the user does not end up paying the utility company $240.56 instead.

Security in the Solution

The solution outlined in this article makes use of a password to authenticate the person opening and saving an InfoPath form.  Since a password by itself does not provide strong authentication, it is combined with the person's user name to add a second layer of security.  If someone else gains knowledge of the password, that person would also have to impersonate the original user before he can gain access to the protected data stored within the form.

The password is not explicitly saved within the form, or anywhere else for that matter.  The user is forced to remember and enter it to both lock and unlock, i.e. encrypt and decrypt, sensitive form fields.  Encryption is used to ensure both privacy and integrity.

Encryption in a Nutshell

Encryption is the conversion of sensitive information known as plain text into illegible cipher text using a bit-string referred to as a key.  The general idea is that the more bits a key has, the stronger the cryptographic algorithm will be.  Nonetheless, each cryptographic algorithm can be broken, given enough time and processing power.

The goals of cryptography are:

1.      Confidentiality (protect data from being read)

2.      Data integrity (detect whether data has been altered)

3.      Authentication (assure data originated from a particular party)

There are three types of encryption: hashing, symmetric encryption, and asymmetric encryption.

Hashing

Hashing algorithms are often one-way functions, i.e. you cannot un-hash hashed data.  Hashing is typically used to detect if data has been tampered with.  On passwords, hashing is used to see if someone knows a password without exposing the password itself.

Symmetric / Asymmetric Encryption

Symmetric encryption algorithms use one key for both encryption and decryption.  The sender and receiver must share this key with each other before they can start exchanging data using symmetric encryption.  Asymmetric algorithms use two separate keys for encryption and decryption.  These keys are known as the public key and the private key.  The private key must be kept secret at all times, while the public key may be shared with everyone.  Symmetric encryption is faster than asymmetric encryption, making it ideal for encrypting large amounts of data.

Encryption in the Solution

The solution outlined in this article makes use of symmetric encryption, i.e. the same key used for encryption is also used for decryption.  The password the user enters into the form is used to generate this key.  Since it is theoretically possible that two users could use the same password to protect their individual InfoPath forms, extra text, called salt, is added to ensure uniqueness of the generated key.  The user name of the logged on user is used as the salt for the key.

Designing the InfoPath Form

We will create a credit card form with a credit card number field (ccNumber) as the sensitive field to protect, and we will add login functionality to the form.

Create a new Microsoft Office InfoPath Project within Microsoft Visual Studio .NET 2003.  When prompted to select a form template for your application, choose Create a new form template. Use the field names and data types shown in Figure 1 to construct the main data source of the form.

 

Figure 1 - Main data source of the InfoPath form

 

 

Drag the fields - except for the isLocked field - onto the form and convert them into the controls shown in Figure 2.

Figure 2 - InfoPath form in design mode

Simulating a Password Control in InfoPath

InfoPath does not come with a Password Control, so you must create your own.  Two password fields are used in this solution: password and passwordAgain (see Figures 1 and 3).  The user is required to enter the same password twice, once in the password field and once in the passwordAgain field.  You must add two validation checks on both password fields: the password fields must not be blank, and the passwords must be the same.

Password fields are usually masked with asterisks (*) for privacy reasons.  Since this functionality is not available in InfoPath, you can set the font of the password and passwordAgain fields to Webdings or Wingdings to simulate masking the passwords as they are entered.  This is the closest you will get to simulating a Password Control in InfoPath.

Figure 3 - Wingdings font used to mask text when typing in passwords

 

Enabling / Disabling the Unlock Button

The Unlock button is disabled whenever the protected field (ccNumber) has been decrypted or when the form is opened for the first time.  It is enabled whenever the form is in a protected state.

The isLocked field is used to determine whether the form contains encrypted data.  It always has one of two values: an empty string or an encrypted version of the text "locked".  If it contains an empty string, form fields are shown in clear text, in which case the Unlock button should be disabled.  If the isLocked field contains an encrypted version of the text "locked", it means that sensitive form fields are being protected, and that the Unlock button should be enabled.

Use conditional formatting to enable/disable the Unlock button by checking whether the isLocked field is blank.

Namespaces

Visual Studio adds two namespaces to the form's code by default: System and Microsoft.Office.Interop.InfoPath.SemiTrust.  Three additional namespaces are required for encryption/decryption purposes: System.Text, System.IO, and System.Security.Cryptography (see Listing 1).

Listing 1 - Additional namespaces required

using System.Text;
using System.IO;
using System.Security.Cryptography;

Encryption / Decryption Methods

The two methods shown in Listings 2 and 3 are used to encrypt and decrypt data.  Both methods take two parameters: a symmetric key and the text to encrypt or decrypt.

Listing 2 - Private method to encrypt data

private string EncryptField(SymmetricAlgorithm
SymmetricKey, string
  ValueToEncrypt)
{
  string base64enc = string.Empty;
  try
  {
    byte[]dataToEncrypt =
Encoding.Unicode.GetBytes(ValueToEncrypt);
    MemoryStream ms = new MemoryStream();
 
    CryptoStream csBase64 = new CryptoStream(ms,
new ToBase64Transform(),
      CryptoStreamMode.Write);
    CryptoStream csRijndael = new
CryptoStream(csBase64,
      SymmetricKey.CreateEncryptor(), CryptoStreamMode.Write);
 
    csRijndael.Write(dataToEncrypt, 0,
(int)dataToEncrypt.Length);
    csRijndael.FlushFinalBlock();
 
    base64enc =
Encoding.ASCII.GetString(ms.GetBuffer(), 0, (int)ms.Length);
  }
  catch (Exception ex)
  {
    thisXDocument.UI.Alert("The following
error occurred: " + ex.Message);
  }
  return base64enc;
}

Listing 3 - Private method to decrypt data

private string DecryptField(SymmetricAlgorithm
SymmetricKey, string
  ValueToDecrypt)
{
  string unencryptedString = string.Empty;
  try
  {
    byte[]dataToDecrypt =
Convert.FromBase64String(ValueToDecrypt);
    MemoryStream ms = new MemoryStream();
 
    CryptoStream csRijndael = new
CryptoStream(ms, SymmetricKey.CreateDecryptor
      (), CryptoStreamMode.Write);
 
    csRijndael.Write(dataToDecrypt, 0,
(int)dataToDecrypt.Length);
    csRijndael.FlushFinalBlock();
 
    unencryptedString =
Encoding.Unicode.GetString(ms.GetBuffer(), 0, (int)
      ms.Length);
  }
  catch
(System.Security.Cryptography.CryptographicException)
  {
    string msg = "Either the password you
entered is incorrect ";
    msg += "or you are not authorized to
view protected data.";
    thisXDocument.UI.Alert(msg);
  }
  catch (Exception)
  {
    string msg = "The InfoPath form has
been tampered with; ";
    msg += "cannot unprotect data.";
    thisXDocument.UI.Alert(msg);
  }
 
  return unencryptedString;
}

The symmetric key is generated from the password entered into the form and the name of the user who is logged onto the system.  The PasswordDeriveBytes class of the System.Security.Cryptography namespace takes 4 parameters:

1.      Password

2.      Key salt

3.      Hash name

4.      Number of iterations to generate the key

This class is used to generate a key from the password.  The user name, which is automatically retrieved with System.Environment.UserName, is used as the salt for the key to ensure its uniqueness.  The private method that generates the symmetric key is shown in Listing 4.

Listing 4 - Private method to generate a symmetric key from a password and user name

private SymmetricAlgorithm GenerateKey(string
password)
{
  string saltValue =
System.Environment.UserName;
  SymmetricAlgorithm symmKey = new
RijndaelManaged();
  byte[]saltValueBytes =
Encoding.ASCII.GetBytes(saltValue);
  PasswordDeriveBytes passwordKey = new
PasswordDeriveBytes(password,
    saltValueBytes, "SHA1", 3);
  symmKey.Key =
passwordKey.GetBytes(symmKey.KeySize / 8);
  symmKey.IV =
passwordKey.GetBytes(symmKey.BlockSize / 8);
  return symmKey;
}

Event Handlers

Two event handlers are used in the form: one to handle the OnSaveRequest event for when the form is saved, and one to handle the OnClick event on the Unlock button.

The OnSaveRequest event handler contains code to encrypt data and empty the two password fields (see Listing 5).  The OnClick event handler for the button contains code to decrypt encrypted data and empty the isLocked field (see Listing 6).

Listing 5 - Code snippet from the OnSaveRequest event handler

// Encrypt the sensitive fields
thisXDocument.DOM.selectSingleNode("/my:myFields/my:isLocked").text
=
  EncryptField(symmKey, "locked");
string ccNumber =
thisXDocument.DOM.selectSingleNode("/my:myFields/my:ccNumber")
  .text;
thisXDocument.DOM.selectSingleNode("/my:myFields/my:ccNumber").text
=
  EncryptField(symmKey, ccNumber);
// Do not save the password; empty the password             
thisXDocument.DOM.selectSingleNode("/my:myFields/my:loginBox/my:password").text
  = string.Empty;
thisXDocument.DOM.selectSingleNode("/my:myFields/my:loginBox/my:passwordAgain")
  .text = string.Empty;

Listing 6 - Code snippet from the btnUnlock_OnClick event handler

// Decrypt the encrypted fields                                         
string ccNumber =
thisXDocument.DOM.selectSingleNode("/my:myFields/my:ccNumber")
  .text;
thisXDocument.DOM.selectSingleNode("/my:myFields/my:ccNumber").text
=
  DecryptField(symmKey, ccNumber);
// Empty the isLocked field so that the Unlock
button is disabled             
thisXDocument.DOM.selectSingleNode("/my:myFields/my:isLocked").text
=
  string.Empty;
How it Works

Saving a Form

The following sequence of events takes place when saving a new InfoPath form and enabling password-protection:

1.      The user opens a new form, fills in the data, and enters a password.

2.      The user initiates the saving of the form by clicking on the Save button, using the File > Save menu item, or closing the form in which case she will be prompted to save the modifications. This will trigger the OnSaveRequest event handler.

3.      A symmetric key is generated from the password entered by the user and her user name.

4.      The text "locked" is encrypted using the symmetric key and the encrypted text is saved in the isLocked field.  The credit card number, which contains sensitive data, is also encrypted using the symmetric key and saved in the ccNumber field it from which it was originally retrieved.

5.      Both the password and passwordAgain fields are emptied before the form is saved, since this data must not be persisted in the form.

6.      The form is saved to disk.

7.      If the form's XML file is opened in e.g. Notepad, the <my:isLocked> and <my:ccNumber> XML nodes will contain encrypted data, while the <my:password> and <my:passwordAgain> XML nodes will be empty.

Opening a Form

The following sequence of events takes place when opening a previously saved and password-protected form:

1.      The user opens a previously saved form.  The credit card number field is shown in an encrypted format, the password fields are empty, and the Unlock button is enabled.

2.      The user enters a password and clicks on the Unlock button.

3.      A symmetric key is generated from the password entered by the user and her user name.

4.      An attempt is made to decrypt the isLocked field.  If successful, the credit card field is decrypted and the unencrypted data is shown.  If the isLocked field cannot be decrypted, this means that the password the user entered is incorrect, the data in the isLocked field within the form's XML file has been tampered with, or the user is not the original person who saved the form.  If decrypting the credit card number field fails while the isLocked field is successfully decrypted, this means that the data in the ccNumber field within the form's XML file has been tampered with.

5.      After the credit card number field has been decrypted, the isLocked field is set to an empty string, indicating that the form fields are now in an unprotected state and the Unlock button is disabled.

Note: It is advisable to back up forms once they have been protected, because if the user forgets the password or the form's data is tampered with, it will not be possible to decrypt the encrypted form fields any more.

Downloads

[Download Code]

Conclusion

You can use the System.Security.Cryptography.PasswordDeriveBytes class to generate a symmetric key from a password.  The name of the logged on user that is returned by System.Environment.UserName can be used as the salt to the generated key.  This ensures uniqueness of the key for every user, even if passwords are the same for different users.

The password is used to both encrypt and decrypt form fields and is not persisted within the form.  The user is responsible for remembering the password; if she forgets the password or if the data within the form is tampered with, decryption will fail and it will not be possible to unlock the form any more.

The technique demonstrated in this article can be used to create self-contained secure password-protected InfoPath forms that provide authentication, privacy, and integrity.



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-24 7:48:13 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search