Application and Network Authentication with the .NET Compact Framework

4/7/2010

Christian Forsberg, businessanyplace

September 2007

Summary

Learn how to authenticate access to devices running Windows Mobile Professional and Windows Mobile Standard, the applications that run on these devices, and network resources that these applications request access to. After a general discussion about security, authentication, and the available options, a sample application and code examples, written in C#, demonstrate practical uses for performing application and network authentication for servers, devices running Windows Mobile Professional, and devices running Windows Mobile Standard. (18 printed pages)

Download ApplicationNetworkAuthentication.msi from the Microsoft Download Center.

Applies To

Microsoft Windows Mobile 6 Professional

Microsoft Windows Mobile 6 Standard

Microsoft Windows Mobile 6 Classic

Microsoft Visual Studio 2005

Microsoft .NET Compact Framework version 2.0

Introduction

Device Authentication

Application Authentication

Network Authentication

Application Authentication Sample

Network Authentication Sample

Code Walkthrough

Conclusion

Introduction

Security in general is highly important in any IT solution. The importance of security is especially true for mobile solutions because a mobile device is easily left behind in a conference room, a taxi, or a hotel room. Also, a mobile device often connects over public networks (such as General Packet Radio Services [GPRS] and hotspots) outside the safer environment that an intranet provides by using firewalls, spam filters, and so on.

Security can roughly be divided into the following categories:

  • Availability and device management
  • Confidentiality and integrity
  • Authentication and authorization

Availability means getting to the information whenever you need it and involves things such as server uptime, fail-over clusters, virus protection, and service level agreements (SLAs). Device management means installing and updating applications and data; backing up the data and user settings; restoring a lost device with applications, data, and personal preferences intact; and so on.

Confidentiality and integrity go hand in hand because most technologies are implemented to cover both. Confidentiality focuses on preventing data from being available to a user who doesn't have the proper access rights (for example, encryption). Integrity is more about preventing data from being tampered with (for example, check sums). Secure Socket Layer (SSL) is an example technology that covers both of confidentiality and integrity. Confidentiality and integrity are also closely related to authentication because they are often dependent on each other.

Authentication means knowing who (users) wants access and providing proof that users really are who they claim to be. Users are usually identified with usernames and passwords are most often the proof. Authorization occurs when authentication is done. Authorization defines what the identified users are allowed to access. This information normally resides in an enterprise directory (such as Active Directory®) and usually involves making the users belong to user groups (roles) that in turn are assigned rights to applications and other system resources.

Authentication on a mobile device can be categorized like the following:

  • Device authentication
  • Application authentication
  • Network authentication

In this article, these three categories are examined in detail.

Device Authentication

This may sound trivial to some, but the authentication of any mobile solution starts with access to the actual device. Most cellular phone users have to provide the personal identity number (PIN) for the Subscriber Identity Module (SIM) card when they turn on their phones. Even if providing a PIN code is also possible on both Windows Mobile Standard and Windows Mobile Professional Editions, an additional device lock can also protect these devices.

On Windows Mobile Professional Edition, this additional device lock is a password, which you can set on the Password screen (tap Start, tap Settings, and then tap Password), as shown in Figure 1.

Bb736226.01dd7f4a-b2d5-43cd-b873-371d77f46c35(en-us,MSDN.10).gif

Figure 1. Password screen on a device running Windows Mobile Professional

After you select the Prompt if device unused for check box, you must enter a time that indicates how long the device must be turned off before the password is required. If you set this box to the minimum (0 minutes), the device requests the password each time someone turns it on. If this option is selected and if the user learns to turn off the device each time he or she stops using the device, the device becomes more secure, and this habit also optimizes battery life.

Next, you must decide the type of password. Even if all of the world's mobile operators and most banks think that a four-digit password is secure enough to protect personal information, this article suggests using a stronger alphanumeric password. As shown in Figure 1, the Strong alphanumeric password type requires the password to contain seven characters and a combination of uppercase and lowercase letters, numerals, or punctuation. When the device prompts the user for the password, each attempt results in a longer and longer response time, which makes guessing the password practically impossible.

On a device running Windows Mobile Standard, you can set the additional device lock on the Enable Phone Lock screen (select Start, select Settings, select More, select Security, and then select Enable Phone Lock), as shown in Figure 2.

Bb736226.e931f20b-d6cb-4417-9518-4224b2147429(en-us,MSDN.10).gif

Figure 2. Enable Phone Lock screen on a device running Windows Mobile Standard

First, you need to select the amount of time the device is inactive before the device prompts you for the password. The minimum value (1 minute) is probably sufficient for protecting the device in most scenarios. If a user forgets the device in a conference room or taxi, another person would probably not have access to it within one minute after the last time it was used. Of course, the password is also required when the device is turned on.

On devices running Windows Mobile Standard, passwords can only consist of numerals, but there is no practical limit to the number of numerals for a password. A password with 30 numerals or one numeral provides a possibility for a more secure device.

For corporations, this article recommends users to require passwords to be entered after 1 minute of device inactivity and create passwords that are at least 12 numerals in length (which results in more possible combinations than the Strong alphanumeric password type on devices running Windows Mobile Professional).

However effective this additional device lock might be, there is always the risk that the password may be obtained through illegitimate means. For increased security, certain devices have more advanced features built into them and a number of third-party products are also available. Examples of authentication methods that are available include generated tokens, pattern matching, smart cards, and even fingerprint and eye scanners.

Application Authentication

As a complement to device authentication, an application can also require application authentication. Just as passwords help protect electronic wallets that keep track of your private information (such as bank account numbers, PIN codes, and so on), your device's applications can prompt users to enter a username and password to be allowed access to the application. Application authentication is especially useful in scenarios where several people use the same device. In scenarios where multiple users use one device, and that device uses device authentication, the device password needs to be shared among all the users.

There are a number of ways that the user can initiate an application password. The user can install the password with the application; the device can retrieve the password from a server when the user first opens the application; or, the user can simply request the password the first time that he or she opens the application. In any case, the password is then stored on the device, and is used every time to verify the identity of the user. The next section will focus on how to store the password on the device in a secure way.

Hashed Passwords

Due to their inherent security risks (such as the possibility of an unauthorized person gaining access to the password), neither storing the password in clear text nor using encryption that could obtain the password by a reversible method are suitable methods for storing the password. To deal with these security risks, the MD5 hash algorithm (RFC 1321) was created. MD5 creates a 128–bit value from any provided string. For example, an empty string always results in the hexadecimal value D41D8CD98F00B204E9800998ECF8427E. This result implies that the security increases the longer the password is. Therefore, it is a good idea to require passwords to be at least 7 characters in length, and if you add the Windows Mobile Professional password requirements (passwords must use mixed case letters, numerals, and punctuation), the security is increased further.

In the Microsoft .NET Framework 2.0, the MD5 algorithm is implemented in the MD5 class of the System.Security.Cryptography namespace. For users of the .NET Compact Framework 1.0, a corresponding implementation can be found in Implementation of the MD5 Algorithm in C# for the Compact Framework on Pocket PC by the Flow Group.

It is not as important where hashed passwords are stored on the device, but you can increase the security by storing them in an encrypted database.

Database Authentication

When you use SQL Server Compact, you can authenticate the local database on the device with a password. This feature allows the database to be encrypted by using the RC4 symmetric encryption algorithm (that many other security standards use, such as SSL) with a key generated from an MD5 hash of the password (remember that the strength of the encryption improves with the length of the password).

File Authentication

There are other ways to store data, and the simplest way is to store the data in an XML file in the file system. Even if this way makes using the data through ADO.NET easy, this way has a few issues. First, XML files grow rapidly due to excessive metadata (such as tags). Second, the data in an XML file is very easy to read for anyone unauthorized because you only need to select the file in File Manager on the device, and the device displays the file in Microsoft Internet Explorer®. Therefore, a need to authenticate the access to the XML file and to compress that file exists.

There are a number of formats for data compression, but the most commonly used format is deflate (RFC 1951). The deflate format is more commonly known as the zip format because it is the format used in normal .zip files. You can use this format in .NET Compact Framework applications by using the excellent (and free) SharpZipLib library, which supports many different compression formats (zip, bzip, gzip, and tar). The full source code is available, and this article's download code sample uses it to compress and encrypt the local data on a Smartphone.

Network Authentication

Although information stored locally on the device can be compromised if the local authentication does not work, the information transmitted over the public network is probably more susceptible. This susceptibility is because the number of people that access the network is much larger than the number of people who can get access to the physical device and because more sensitive information is transferred over the network—even if the user never stores it locally.

If clients connect directly to a server by using low-level technologies, like TCP/IP sockets, the most common option is for the device client application to use XML Web services to communicate with the server. Therefore, the focus for network authentication is authentication mechanisms that are related to Web (read HTTP) technologies.

The most common Web technology authentication options are the following:

  • Basic Authentication
  • Digest Authentication
  • NTLM Authentication
  • Web service extensions

Basic Authentication

In 1996, the HTTP 1.0 standard (RFC 1945) included the specification for a Basic Access Authentication scheme that is a non-secure method of filtering unauthorized access to resources on an HTTP server. Because the passwords are sent over the network in clear text (Base64 encoded text), the standard is based on the assumption that the connection is secure. Such security can be provided through SSL. The .NET Compact Framework 1.0 supports Basic Authentication and is very straightforward to implement, as shown in the following code example.

MyWebService myWebService = MyWebService();
myWebService.Credentials = new NetworkCredential("username", "password");

When this is code is finished running, it is possible to call the (Web) methods on the Web reference myWebService instance.

Digest Authentication

Another option that is available in the .NET Compact Framework 1.0 is to use Digest Authentication (RFC 2617), which was developed as a result of Basic Authentication providing such weak security. The Digest Authentication scheme is dependent on the HTTP 1.1 standard (RFC 2616) and is based on a simple challenge-response paradigm; the server challenges the client by using a nonce value (that varies with time). A valid response from the client contains the MD5 hash of the username, the password, the given nonce value, the HTTP method, and the requested Uniform Resource Identifier (URI). In this way, the password is never sent over the network in clear text.

To set up Digest Authentication on a server that runs Windows, a Windows 2000 (or later) domain controller with an Active Directory directory service is required. The user and the server that runs Internet Information Services (IIS) must be members of, or trusted by, the same domain controller. The user must have a valid user account stored in the Active Directory directory service on the domain controller, and the user account must have the account option Store password using reversible encryption enabled selected; otherwise, IIS cannot validate the MD5 hash from the client that includes the password. To select this account option, the user must reset or re-enter the password. For more information about setting up Digest Authentication on the server side, see the local IIS Help file.

The MapPoint Web Service is a good example of a public XML Web service that uses Digest Authentication to authenticate the calls made to the Simple Object Access Protocol (SOAP) application programming interfaces (APIs). To make authentication more efficient, the recommendation is to set the Preauthentication property on the SOAP proxy. Setting this property eliminates extra round trips for authentication purposes. The following code is an example of how to set this property.

RenderServiceSoap renderService  = new RenderServiceSoap();
renderService.Credentials = new NetworkCredential("username", "password");
renderService.PreAuthenticate = true;

After you've set this property, the application can call the (Web) methods on the SOAP proxy (renderService).

Windows Authentication

Even if the correct term is NTLM (NT LAN Manager) Authentication, this option is normally referred to as Integrated Windows Authentication (as in IIS) or simply Windows Authentication. You only need to enable the Integrated windows authentication check box on the virtual directory in IIS and install the .NET Compact Framework 2.0 on the devices. If the NetworkCredential object (as shown previously) is used, the clients are authenticated by using Windows Authentication.

Web Service Extensions

WS-Security requires heavy (both asymmetric and symmetric) encryption for every call, which is difficult on mobile devices such as those running Windows Mobile Professional or Windows Mobile Standard. Therefore, a better alternative for mobile devices is WS-SecureConversation, where most of the heavy encryption is done on the first call, and consecutive calls need to do less performance-expensive (symmetric) encryption. This alternative is very similar to the way that SSL works, even if SSL does the same thing on a lower (network) level. With WS-SecureConversation (as with all of the standards within Web Service Extensions), the idea is to do the processing on the message level.

Application Authentication Sample

The application authentication sample was created with Microsoft Visual Studio .NET 2005, is written in C#, and targets the .NET Compact Framework. The sample application shows how to do application authentication by validating passwords that are stored in a local database or XML file on the device.

The purpose of the sample application is to show how an application that runs on a device running Windows Mobile Professional or Windows Mobile Standard can authenticate a user before it allows the user access to the application's functionality. The assumption is that the authentication should be done locally without the need for a network connection. Figure 3 shows a typical logon screen where the user can enter the username and password.

Bb736226.5004f9db-8c29-43e3-9bc5-b3d491fb6cb4(en-us,MSDN.10).gif

Figure 3. Logon screen for the local authentication sample on a device running Windows Mobile Professional

When you tap the Login button, the application validates the Username and Password by using a local database. In the sample, the database is created when the application starts, but you can deploy the database in many different ways (install with the application, synchronize with a server database, and so on).

Figure 4 shows the corresponding logon screen for a Smartphone.

Bb736226.a57f3355-dbd8-4e68-81f7-305c0caa46a8(en-us,MSDN.10).gif

Figure 4. Logon screen for the local authentication sample on a Smartphone

On a Smartphone, although a local database can be used as well, the local data is stored as a DataSet object in an XML file that is both compressed and encrypted (in a .zip file). Similar to the Windows Mobile Professional sample, you can deploy the .zip file in many ways. The .zip file is created during startup of the sample application.

Network Authentication Sample

The network authentication sample was created with the same tools as the previous sample. This sample shows how to authenticate by using the Windows (NTLM) Authentication. Similar to the previous sample, Figure 5 shows a typical logon screen where the user can enter a username and password.

Bb736226.8e56aa6e-cdcb-4607-95b8-ac470b98feb5(en-us,MSDN.10).gif

Figure 5. Logon screen for the Windows (NTLM) Authentication sample on a device running Windows Mobile Professional

When you tap the Login button, the application uses the Username and Password to attempt a call to an XML Web service. Because this XML Web service requires Windows Authentication, the Web server sends a challenge that the client responds to, to enable further communication. An unsuccessful attempt results in an informative message (User NOT authorized), and as soon as the authentication is successful, further calls do not require any authentication. You can test this by changing the username or the password after the first successful call, and you will still get a successful response.

Figure 6 shows the corresponding sample for Smartphone.

Bb736226.1bff41ac-98a8-46b0-95ed-61df8cb8b379(en-us,MSDN.10).gif

Figure 6. Logon screen for the Windows (NTLM) Authentication sample on a Smartphone

The logic for the Smartphone sample is identical to the Windows Mobile Professional sample.

Code Walkthrough

This section describes the code behind both of the application authentication and the network authentication samples.

Application Authentication Sample

The Windows Mobile Professional sample uses a SQL Server Compact database that is encrypted by using a password. The code to set up the database looks like the following.

string applicationPath =
  Path.GetDirectoryName(this.GetType().Assembly.GetName().CodeBase);
string localDatabasePath = applicationPath + Path.DirectorySeparatorChar +
  "EncryptedDatabase.sdf";
string databasePassword = "pe4eGaWR46a4e+UPR-c??&wa!uFu#asw";
string localConnectionString = "Data Source=" + localDatabasePath +
  ";Password=" + databasePassword;
string localDatabaseScriptPath = applicationPath +
  Path.DirectorySeparatorChar + "EncryptedDatabase.sql";

// Create only if it doesn't exist
if(File.Exists(localDatabasePath))
  return;

// Create local database
using(SqlCeEngine engine = new SqlCeEngine(localConnectionString +
                                           ";Encrypt Database=True"))
  engine.CreateDatabase();

// Add table and user row
using(SqlCeConnection cn = new SqlCeConnection(localConnectionString))
{
  cn.Open();
  SqlCeCommand cmd = cn.CreateCommand();
  StreamReader sr = new StreamReader(localDatabaseScriptPath);
  string s;
  string commandText = string.Empty;
  while(sr.Peek() > 0)
  {
    s = sr.ReadLine();
    if(s.Trim().ToUpper() == "GO")
    {
      cmd.CommandText = commandText;
      cmd.ExecuteNonQuery();
      commandText = string.Empty;
    }
    else
      commandText += s;
  }
}

First, the code retrieves the application path and uses it to create the full path of both the database itself and a script file, which is used to set up the database. A database password is hard coded, and even though the password can be any value, it is probably best to create it by using a password generation tool. The password generation tool should mix case and include both numbers and punctuation. But you should be observant because some punctuation characters (like an equal sign [=] and a semicolon [;]) are not allowed in a connection string. Remember that the encryption strength is relative to the key length, and that this password will never be entered by anyone, so there is no need for a short and readable password. In the previous code, a 256-bit password is used which should provide very high security.

After the code establishes a database path and the password, a connection string is set up, which creates the database. The connection string needs to include an extra parameter (Encrypt Database=True) when the database is created. This extra parameter is not necessary when the application opens the database later. The loop reads the script file and submits the content to the database.

The script file looks like the following.

CREATE TABLE Users (
  UserID uniqueidentifier PRIMARY KEY DEFAULT NEWID() NOT NULL,
  Name NVARCHAR(50) NOT NULL,
  UserName NVARCHAR(30) NOT NULL,
  PasswordHash NVARCHAR(32) NOT NULL,
  DomainName NVARCHAR(30) NULL,
  EmailAddress NVARCHAR(50) NOT NULL
)
GO

INSERT INTO Users (Name, UserName, PasswordHash, DomainName, EmailAddress)
VALUES('Some One', 'someone', 'fa6a602c680673f462cab11b2b07218e', NULL,
  'someone@microsoft.com')
GO

As this code example shows, this script file looks like any database script file; therefore, you can reuse this code in most situations where a local SQL Server Compact database should be initialized.

The observant reader notices that the password column (PasswordHash) has some odd content—the MD5 hash value of the username and the password combined (in this example, the string "someonetest"). Even if standards are used for encryption, it is small individual inventions like this (concatenating the username and password to calculate the hash value) that makes it much harder for anyone to crack the system. In a highly secure environment, only this hash value is stored in any system. The value is generated when the user changes the password, and because there is no way to get to the original password, the password needs to be reset if the user should forget it.

In either version of the .NET Framework (desktop or Compact), the code to generate the MD5 hash value looks like the following.

private string GetMD5(string stringToHash)
{
  MD5 md5 = MD5CryptoServiceProvider.Create();

  // Convert a string to an array of bytes
  byte[] buffer = Encoding.ASCII.GetBytes(stringToHash);

  // Create a hash value from the array
  byte[] hash = md5.ComputeHash(buffer);

  // Convert a hash to a string
  string s = string.Empty;
  foreach(byte b in hash)
    s += b.ToString("x2");

  return s;
}

As mentioned previously, if this sample was used with the .NET Framework 1.0 it could use the MD5 implementation by the Flow Group. The code to authenticate (when the user taps the Login button) looks like the following.

// Get the MD5 hash from the user name and password that is provided
string userMD5 = GetMD5(userNameTextBox.Text + passwordTextBox.Text);

// Get the password hash from the database
string applicationPath =
  Path.GetDirectoryName(this.GetType().Assembly.GetName().CodeBase);
string localDatabasePath = applicationPath + Path.DirectorySeparatorChar +
  "EncryptedDatabase.sdf";
string databasePassword = "pe4eGaWR46a4e+UPR-c??&wa!uFu#asw";
string localConnectionString = "Data Source=" + localDatabasePath +
  ";Password=" + databasePassword;
string dbMD5;
try
{
  using(SqlCeConnection cn = new SqlCeConnection(localConnectionString))
  {
    cn.Open();
    SqlCeCommand cmd = cn.CreateCommand();
    cmd.CommandText = "SELECT PasswordHash FROM Users WHERE UserName='" +
      userNameTextBox.Text + "'";
    dbMD5 = cmd.ExecuteScalar().ToString();
  }

  // Check password hash
  if(userMD5 == dbMD5)
    MessageBox.Show("User authorized!", this.Text);
  else
    MessageBox.Show("User not authorized!", this.Text);
}
catch(SqlCeException ex)
{
  string s = ex.Message;
  int i = s.IndexOf('[');
  if(i > 1)
    s = s.Substring(0, i - 2);
  MessageBox.Show(s + "!", this.Text, MessageBoxButtons.OK,
    MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
}
catch(Exception ex)
{
  MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK,
    MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
}

The code calculates the password hash for the entered username and password, and then the code retrieves the stored hash value from the local database by using the database password. Then, the code compares the two hash values and presents the result to the user. Even if the exception handling that is implemented in the code presents errors (both from the database and other) in a user-friendly way to the user, it is important not to provide too much help because an unauthorized person may be trying to force the authentication. Therefore, messages like "the username was correct, but not the password" or even "username not found" should be avoided.

On the Smartphone, although SQL Server Compact could be used as well, the data is provided in an XML file (from a DataSet object) that looks like the following.

<DataSet>
  <xs:schema id="DataSet" 
   xmlns:xs="https://www.w3.org/2001/XMLSchema"
   xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="DataSet" msdata:IsDataSet="true">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="Users">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="UserID" msdata:DataType="System.Guid"
                 type="xs:string" minOccurs="0" />
                <xs:element name="Name" type="xs:string" minOccurs="0" />
                <xs:element name="UserName" type="xs:string" minOccurs="0" />
                <xs:element name="PasswordHash" type="xs:string"
                 minOccurs="0" />
                <xs:element name="DomainName" type="xs:string"
                 minOccurs="0" />
                <xs:element name="EmailAddress" type="xs:string"
                 minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <Users>
    <UserID>30305200-83cb-11c5-8000-d455befdca22</UserID>
    <Name>Some One</Name>
    <UserName>someone</UserName>
    <PasswordHash>fa6a602c680673f462cab11b2b07218e</PasswordHash>
    <EmailAddress>someone@microsoft.com</EmailAddress>
  </Users>
</DataSet>

It is a recommendation that you include the XML schema in the file because this schema helps validate the data. In this example (when all columns are of type string), it is not as important as when handling more complex data structures (which are normally the case in any real-world scenario). The data is the same as the data that the Windows Mobile Professional sample used, and you can create a DataSet object like this one with the following code.

using(SqlCeConnection cn = new SqlCeConnection(connectionString))
{
  cn.Open();
  SqlCeDataAdapter da = new SqlCeDataAdapter("SELECT * FROM Users", cn);
  DataSet ds = new DataSet();
  da.Fill(ds, "Users");
  FileStream fs = File.OpenWrite(fileName);
  XmlTextWriter xtw = new XmlTextWriter(fs, Encoding.UTF8);
  ds.WriteXml(xtw, XmlWriteMode.WriteSchema);
  xtw.Close();
  fs.Close();
}

This is the code to use on the device, and you can use a very similar code on a desktop computer by removing all of the "Ce" phrases in the ADO.NET classes (SqlConnection, SqlDataAdapter, and so on). Also, the stream and writer objects are not required on the desktop computer.

With this file as a prerequisite, the Smartphone sample sets up the encrypted local storage by using the following code.

string applicationPath =
  Path.GetDirectoryName(this.GetType().Assembly.GetName().CodeBase);
string localDataSetPath = applicationPath + Path.DirectorySeparatorChar +
  "EncryptedDataSet.zip";
string dataSetPassword = "pe4eGaWR46a4e+UPR-c??&wa!uFu#asw";
string localDataSetXmlPath = applicationPath + Path.DirectorySeparatorChar +
  "EncryptedDataSet.xml";

// Create only if it doesn't exist
if(File.Exists(localDataSetPath))
  return;
 
// Load DataSet object from the text file
FileStream fs = File.OpenRead(localDataSetXmlPath);
XmlTextReader xtr = new XmlTextReader(fs);
DataSet ds = new DataSet();
ds.ReadXml(xtr, XmlReadMode.ReadSchema);
xtr.Close();
fs.Close();

// Save to an encrypted .zip file
ZipOutputStream zs = new ZipOutputStream(File.OpenWrite(localDataSetPath));
zs.Password = dataSetPassword;
zs.PutNextEntry(new ZipEntry(Path.GetFileName(localDataSetXmlPath)));
XmlTextWriter xtw = new XmlTextWriter(zs, Encoding.UTF8);
ds.WriteXml(xtw, XmlWriteMode.WriteSchema);
xtw.Close();
zs.Close();
ds = null;

First, the code retrieves the application path and uses it to create the full path of both the XML and .zip files. Then, the XML file is read into a DataSet object that creates the .zip file with the XML file as the only entry. The .zip file is also encrypted by using the same password that the Windows Mobile Professional sample used.

Even if this code was written to use the SharpZipLib library on the device, you could also create the .zip file on the desktop computer (or server) and distribute it with the application. It shouldn't be too difficult to find tools to create an encrypted .zip file that contains an XML file with the DataSet object; it can even be done using the Send To > Compressed (zipped) folder functionality in Windows Explorer). One advantage of using standards is the many tools that are available for different platforms.

The code to authenticate the user (when the user presses Login soft key) looks like the following.

// Get the MD5 hash from the user name and password that is provided
string userMD5 = GetMD5(userNameTextBox.Text + passwordTextBox.Text);

string applicationPath =
  Path.GetDirectoryName(this.GetType().Assembly.GetName().CodeBase);
string localDataSetPath = applicationPath + Path.DirectorySeparatorChar +
  "EncryptedDataSet.zip";
string dataSetPassword = "pe4eGaWR46a4e+UPR-c??&wa!uFu#asw";

// Load the DataSet object from the .zip file
ZipInputStream zs = new ZipInputStream(File.OpenRead(localDataSetPath));
zs.Password = dataSetPassword;
zs.GetNextEntry();
XmlTextReader xtr = new XmlTextReader(zs);
DataSet ds = new DataSet();
ds.ReadXml(xtr, XmlReadMode.ReadSchema);
xtr.Close();
zs.Close();

// Get the password hash from the DataSet object
string dbMD5 = string.Empty;
DataRow[] drs = ds.Tables["Users"].Select("UserName='" + userNameTextBox.Text + "'");
if(drs.Length == 1)
  dbMD5 = drs[0]["PasswordHash"].ToString();

// Check password hash
if(userMD5 == dbMD5)
  messageLabel.Text = "\r\nUser authorized!";
else
  messageLabel.Text = "User NOT authorized!\r\nPlease try again.";

After the code calculates the password hash for the entered username and password, the code retrieves the stored hash value from the local database by using the .zip file's password. Reading from the .zip file is very similar to reading a file from the file system (see the previous code example). Finally, the code compares the two hash values and presents the result to the user in a label on the same form. Presenting the result on the same form improves the user experience compared to using a separate form (as would be the case if you use the MessageBox class).

Network Authentication Sample

The sample code to use Windows Authentication uses an XML Web service that implements a trivial method, as shown in the following code example.

[WebMethod]
public string HelloWorld(string name)
{
  return "Hello " + name + "!";
}

After you create a Web reference to the XML Web service, the code to authenticate is identical to the code for Basic or Digest Authentication, as shown in the following code example.

try
{
  WebServices.Service ws = new WebServices.Service();
  ws.Credentials = new NetworkCredential(userNameTextBox.Text,
    passwordTextBox.Text);
  ws.PreAuthenticate = true;
  string s = ws.HelloWorld(userNameTextBox.Text);
  MessageBox.Show("User authorized!", this.Text);
  MessageBox.Show(s);
}
catch(WebException ex)
{
  HttpWebResponse resp = (HttpWebResponse)ex.Response;
  if(resp.StatusCode == HttpStatusCode.Unauthorized)
    MessageBox.Show("User NOT authorized!",this.Text);
  else
    throw;
}    

When the virtual directory for the XML Web service in the Web server (IIS) has (Integrated) Windows Authentication enabled, the authentication manager uses the custom authentication module to respond to the authentication challenge that the server sends. You can avoid unnecessary network traffic by using preauthentication by setting the PreAuthenticate property to true.

For details about implementing the custom authentication module for Windows (NTLM) Authentication, see this article's download code sample.

Conclusion

Most security considerations begin with authentication. If only the correct users are allowed access to device and networks resources, better security is achieved. If you remember that physical device access and network access are the most important issues, application authentication can make sure that only authorized user’s access business information that is stored locally. Building on industry standards, authentication can be achieved with affordable efforts.