Tuesday, July 13, 2010

Encrypt / Decrypt Strings using Visual Basic and C# .Net

I have created a few handy methods for encrypting and decrypting a string using the .net frameworks Tripple DES Crypto Service Provider.

I have posted the Encryption / Decryption code below in both VB and C# .Net.


Visual Basic Version:

Imports System
Imports System.IO
Imports System.Security.Cryptography

' Triple DES String Encryptor / Decryptor
' Austin Scott
' June 17, 2010
Public Class FormTestEncryptDecrypt

' Key For Triple DES
Private key() As Byte = {34, 12, 93, 23, 7, 53, 2, 99, 19, 25, 27, 200, 192, 32, 60, 57, 87, 102, 183, 123, 34, 22, 65, 42}
' IV for Triple DES
Private iv() As Byte = {69, 110, 68, 26, 69, 178, 200, 219}

Private Sub ButtonEncrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonEncrypt.Click
TextBoxEncrypt.Text = Encrypt(TextBoxEncrypt.Text)
End Sub


Private Sub ButtonDecrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonDecrypt.Click
TextBoxDecrypt.Text = Decrypt(TextBoxDecrypt.Text)
End Sub

' =-=-=-=-=-=-=-=-=-=-=---=-=-
' Encrypt a string value (to a Comma Separated byte array) using triple DES
' =-=-=-=-=-=-=-=-=-=-=---=-=-
Public Function Encrypt(ByVal plainText As String) As String

Dim utf8encoder As Text.UTF8Encoding = New Text.UTF8Encoding()
Dim inputInBytes() As Byte = utf8encoder.GetBytes(plainText)

Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateEncryptor(Me.key, Me.iv)

Dim encryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write)

cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
encryptedStream.Position = 0

Dim result(encryptedStream.Length - 1) As Byte
encryptedStream.Read(result, 0, encryptedStream.Length)
cryptStream.Close()

Dim sbResult As Text.StringBuilder = New Text.StringBuilder()

For iPos As Int16 = 0 To result.Length - 1
If (iPos = result.Length - 1) Then
sbResult.Append(result(iPos))
Else
sbResult.Append(result(iPos))
sbResult.Append(",")
End If
Next iPos

Return sbResult.ToString

End Function


' =-=-=-=-=-=-=-=-=-=-=---=-=-
'Decrypt a string value (Comma Separated byte array) using triple DES
' =-=-=-=-=-=-=-=-=-=-=---=-=-
Public Function Decrypt(ByVal stringToDecrypt As String) As String


Dim byteArrayString() As String = stringToDecrypt.Split(",")
Dim inputInBytes(byteArrayString.Length - 1) As Byte
For iPos As Int16 = 0 To byteArrayString.Length - 1
inputInBytes(iPos) = Convert.ToByte(byteArrayString(iPos))
Next iPos

Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateDecryptor(Me.key, Me.iv)

Dim decryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
decryptedStream.Position = 0

Dim result(decryptedStream.Length - 1) As Byte
decryptedStream.Read(result, 0, decryptedStream.Length)
cryptStream.Close()
Dim myutf As Text.UTF8Encoding = New Text.UTF8Encoding()
Return myutf.GetString(result)
End Function


C# Version:


// Key For Triple DES - Modify these
private byte[] key = { 34, 12, 93, 23, 7, 53, 2, 99, 19, 25, 27, 200, 192, 32, 60, 57, 87, 102, 183, 123, 34, 22, 65, 42 };
// IV for Triple DES - Modify these
private byte[] iv = { 69, 110, 68, 26, 69, 178, 200, 219 };

public Form1()
{
InitializeComponent();
}

private void ButtonEncrypt_Click(object sender, EventArgs e)
{
TextBoxEncrypt.Text = Encrypt(TextBoxEncrypt.Text);
}


private void ButtonDecrypt_Click(object sender, EventArgs e)
{
TextBoxDecrypt.Text = Decrypt(TextBoxDecrypt.Text);
}


// =-=-=-=-=-=-=-=-=-=-=---=-=-
// Encrypt a string value (to a Comma Separated byte array) using triple DES
// =-=-=-=-=-=-=-=-=-=-=---=-=-
private String Encrypt(string plainText)
{

UTF8Encoding utf8encoder = new UTF8Encoding();
byte[] inputInBytes = utf8encoder.GetBytes(plainText);
TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform = tdesProvider.CreateEncryptor(key, iv);

MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write);

cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;

byte[] result = new byte[encryptedStream.Length];
encryptedStream.Read(result, 0, Convert.ToInt32(encryptedStream.Length));
cryptStream.Close();

// Create a comma separated string of the encrypted bytes values
StringBuilder sbResult = new StringBuilder();

for (Int16 iPos = 0; iPos <= result.Length - 1; iPos++)
{
if (iPos == result.Length - 1)
{
sbResult.Append(result[iPos]);
}
else
{
sbResult.Append(result[iPos]);
sbResult.Append(",");
}

}

return sbResult.ToString();
}


// =-=-=-=-=-=-=-=-=-=-=---=-=-
// Decrypt a string value (Comma Separated byte array) using triple DES
// =-=-=-=-=-=-=-=-=-=-=---=-=-
private String Decrypt(string stringToDecrypt)
{
string[] byteArrayString = stringToDecrypt.Split(',');
byte[] inputInBytes = new byte[byteArrayString.Length];
for (Int16 iPos = 0; iPos <= byteArrayString.Length - 1; iPos++)
{
inputInBytes[iPos] = Convert.ToByte(byteArrayString[iPos]);
}

TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform = tdesProvider.CreateDecryptor(key, iv);

MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write);

cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position = 0;

byte[] result = new byte[decryptedStream.Length];
decryptedStream.Read(result, 0, Convert.ToInt32(decryptedStream.Length));
cryptStream.Close();
UTF8Encoding myutf = new UTF8Encoding();
return myutf.GetString(result);
}

Tuesday, June 8, 2010

Java WebStart - "Unable to completely uninstall application" Problem

Today I ran into an annoying problem when I needed to re-install a Java WebStart application.
When I opened up the Control Panel and Selected Add Remove Programs on my Windows XP computer, and selected the Java WebStart application I wanted to uninstall, the following message appeared:

"Unable to completely uninstall application"


After trying a few different tricks, I was able to uninstall the application using the Java Control Panel by:

  1. Opening the Control Panel and Selecting the Java option
  2. From the Java Control Panel under the General Tab in the Temporary Internet Files group box I clicked the View... button.
  3. The Java Cache Viewer appears.
    I found the application I wanted to uninstall on the list.
  4. Finally I right clicked the application and selected Delete

After I deleted the application from the Java Control Panel I was able to re-install the Java WebStart application and continue with my work.

Monday, May 17, 2010

Force IIS7 to run applications in x86 (32 bit)

The other day I ran into a problem where my WCF C# .net application was being run in x64 bit mode. Normally this would not be an issue but my C# application was linking to some old unmanaged dlls that were compiled to only run in x86 mode.

The error message I was seeing is IIS7 was:
Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.BadImageFormatException: Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Here is how I was able to force IIS7 to use x86 mode on a 64 bit version of Windows Server 2008:
  1. First I needed to change my C# applications to compile in x86 mode rather than "Mixed Platforms".
    I did this by right clicking my solution and opening the Properties and then selecting the Configuration Properties tree branch in Visual Studio 2008.

  2. Next I opened IIS7 Manager (Internet Information Services Manager):
    Control Panel -> Administrative Options -> Internet Information Services Manager

  3. In the IIS7 Manager I selected the Application Pools leaf for my server.





  4. I right clicked on the Classic .Net AppPool.

    (you may want to use the Default AppPool depending on if you application was originally designed for IIS7 )

    And selected Advanced Settings...





  5. Under Advanced Sttings there is an option called
    "Enable 32-Bit Applications"

    Switch that option to True





  6. Open your website and find your Application.
    Change your application to use the Classic .Net AppPool
    (or Default AppPool depending on your application )

  7. Restart IIS7

Tuesday, May 11, 2010

Windows Vista \ Windows 7 \ Windows Server 2008 folder permissions

My C# Log File or Configuration File throws a System.UnauthorizedAccessException in Vista / Windows 7 / Windows Server 2008!

I am sure most people have encountered an Access Exception in C# .Net after installing an application that was:

  • Written to run on Windows XP

  • Written to run Windows Server 2003

  • Written to run on an even earlier version of Windows...

after installing it on a :

  • Windows Vista computer

  • Windows 7 computer

  • Windows Server 2008 server

System.UnauthorizedAccessException

at LogOMatic.Logger.Append(String message, Priority level, Priority logPriorityLevel)

at SyncInvokeMemConnect(Object , Object[] , Object[] )

at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)


Back in the good old days of windows application development files could be written willy-nilly across the hard drive! They were glorious days, but all good things must come to an end.

Modern windows applications (Windows Vista, Windows 7, Windows Server 2008) are expected to only read and write files to certain predefined folder paths.

http://msdn.microsoft.com/en-us/library/system.environment.specialfolder%28VS.100%29.aspx

In the good old days we used to use the default execution path or the assembly path to reference our configuration or log files like so:

// THE OLD XP WAY
String assmLoc = Assembly.GetExecutingAssembly().Location;

Now we need to use the Environment.SpecialFolder class.

If you are running a client side application you can use the ApplicationData special folder like the following example:

// New UAC Way
String APPLICATION_NAME = "TEST";

String assmLoc = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+"\\"+APPLICATION_NAME;


This will put your configuration or log file in the hidden folder:

Windows Vista / Windows 7 / Windows Server 2008:

C:\ProgramData\\Application Data\TEST

Windows XP / Windows Server 2003:

C:\Documents and Settings\\Application Data\TEST

If you are running a windows service or WCF (Windows Communication Foundation) applciation (like a SOAP web service) you will need to use the CommonApplicationData special folder entry.

//New UAC way for WCF or Services
String APPLICATION_NAME = "TEST";

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)+"\\"+APPLICATION_NAME

This will put your configuration or log files into the Hidden folder C:\ProgramData\ (could be on a different partition depending on your server configuration):

Windows Vista / Windows 7 / Windows Server 2008:

C:\ProgramData\TEST

Windows XP / Windows Server 2003:

C:\Documents and Settings\TEST




About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca

How to Debug WCF

In this short tutorial I will show you how to “Attach to process...” a WCF web service using Visual Studio and IIS6 or IIS7

There are a few minimum requirements that must be met in order to attach to a WCF ( Windows Communication Foundation ) service process:

  1. You must add the following entry to your:
    Web.config
    or

    app.config
    file to enable debugging:

  1. You must be running at least Visual Studio Pro, Premium, and Ultimate editions
    Sorry, no debugging in Express ( at least not for C# )

  2. These instructions only work with IIS6 or IIS7

There are also some limitations of debugging WCF that should be considered.

Once you have everything setup correctly ( you may need to restart IIS ) you can open visual studio and select:

Tools -> Attach to Process...

(Ctrl + Alt + P )

Check off both the Show processes... check boxes at the bottom of the dialog:

  • Show processes from all users

  • Show processes in all sessions


And find the process named:

w3wp.exe

NOTE:
If the process w3wp.exe does not appear in the list. Try running the web service using the WCF Test Client. After the service is run the w3wp.exe process should appear.

Attach the debugger to that process and you should be able to step through your code.




References:

http://msdn.microsoft.com/en-us/library/bb157687.aspx

About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca

Monday, May 10, 2010

IIS 7.0 http 500.24

IIS7 Application Pool Integrated Mode Causing Error 500.24

After migrating a C# Windows Communication Foundation (WCF) IIS6 application that was running on Windows Server 2003 to a Windows Server 2008 machine that is running IIS7, I received the following error message:

Server Error In Application "DEFAULT WEB SITE" HTTP Error 500.24 - Internal Server Error An ASP.NET setting has been detected that does not apply in Integrated Managed pipeline mode.



I was able to resolve this issue by following these steps:

  1. Open the IIS 7 Manager (Internet Information Services Manager):
    Start -> Control Panel -> Administrative Tools

  2. Expand your web site tree and Right Click on Application Pools


  3. Right Click on the Classic .Net AppPool (Application Pool) option

  4. Under the drop down labeled "Managed pipeline mode:"
    Select:
    Classic




  5. Restart IIS7 by right clicking on your server icon and selecting stop.
    Once IIS has stopped right click on the server icon again and select start.


Your migrated .Net application should now be running under IIS7.


What does IIS7's AppPool (Application Pool) Integrated Mode Do?

According to the IIS website running your application in Integrated mode will take advantage of some of the exciting new features offered in IIS7 such as:
If your application has not be designed to take advantage of these features (such as an application that was originally written to run on an IIS6 web server) then you don't really need to run your application in integrated mode. Ideally you should rework your application to take advantage of the new IIS7 features and resolve any incompatibilities with IIS7. Running in Classic mode .Net app pool mode will at least get your application up and running on a new machine while you work to enhance your code base.


References:
IIS Website Post: ASP.NET 2.0 Breaking Changes on IIS 7.0


About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca

Thursday, May 6, 2010

Configure WCF on IIS7 and Windows Server 2008

Last week I needed to migrate a C# .Net WCF (Windows Communication Foundation) application from:
  • Microsoft Windows Server 2003 machine running IIS version 6

    TO
  • Microsoft Windows Server 2008 machine running IIS version 7
I have never had the opportunity to work with Server 2008 or IIS7 before so naturally I ran into a few bumps in the road. Hopefully this article will save you a few hours of head pounding that I went through.

Problem #1:
IIS not recognize my SVC service files!

When I tried to load up my service file:
http://www.localhost/MyTestService/service.svc

I received the following error message:

HTTP Error 404.3 - Not Found

The page you are requesting cannot be served because of the extension configuration. If the page is a scr

ipt, add a handler. If the file should be downloaded, add a MIME map.



You can see the reason behind the problem if you open up the IIS Manager:
Start -> Administrative Tools -> Internet Information Services Manager

And then click the Default Web Site (or your website instance) and in the Feature View open the Handler Mappings.


When you scroll through the list of Handler Mappings you will notice that there are no listings for the SVC extension.

Its hard to run a WCF web service on IIS if the web service SVC extension is not being recognized! I already had the .Net framework 3 installed on the Server 2008 machine so it did not make sense to why it was not working. I tried to manually add the SVC extension to the MIME maps but that did not work.

Here is how I was able to resolve this issue:

  1. I opened up the Programs and Features of the Windows Server 2008.
    Start -> Control Panel -> Programs and Features

  2. I clicked on the Turn Windows Features on or off link on the left hand side of the Programs and Features window.

  3. The Server Manager window appeared.
    So next I selected the Features tree branch and clicked the Add Feature button on the right side of the window.

  4. The Add Features Wizard window appeared.
    I expanded the tree branch labeled:
    .Net Framework 3.0 Features

    And then the tree branch labeled:
    WCF Activation

    I checked off all of the Check Boxes under WCF:
    HTTP Activation Non-HTTP Activation



  5. Finally I clicked the Install button. After several minutes of installing away I was ready to test if my changes had worked.

  6. You can insure that the SVC handler mapping is properly configured by opening up the IIS Manager:
    Start -> Administrative Tools -> Internet Information Services Manager

    And then click the Default Web Site (or your website instance) and in the Feature View open the Handler Mappings.

    If you scroll down the list you should see the SVC handlers have been configured.






Hopefully this will help someone to overcome this issue with a clean Server 2008 and IIS7 installation... or at the very least it will help to remind me how I got it working the next time I need to handle this.

About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca