Protect your IM (Instant Messenger) conversations by encrypting them






4.63/5 (25 votes)
Oct 20, 2005
6 min read

154488

2767
Learn how to encrypt IM (Instant Messenger) conversations.
IMEncryptor: Encrypt your IM (Instant Messenger) conversations.
Ficture_1. The big picture.
Contents
- Introduction
- Features
- Prerequisites
- The pieces of the puzzle or ... what are we playing with?
- The idea - in words
- The three window areas.
- Sending an encrypted line of message.
- Decrypting an encrypted incoming message.
- The idea - in code
- Finding the HWNDs of the three window areas we are interested in.
- Sending an encrypted line of message.
- Decrypting an encrypted incoming message.
- How to use IMEncryptor
- TODO list
- Version history
Introduction
Nowadays everybody knows how to make use of a packet sniffer and probably (if the channel is not already secured) find some sensitive information. By placing such a tool "under the skin" of your network in a couple of sensitive zones, someone could get for example, the Yahoo Messenger conversations. That's because (and you probably know this fact) these conversations are not encrypted.
Short story
Some time back in 2000, there was a Yahoo Messenger Enterprise Edition version. This version used encryption to protect conversations. Since the big corporations didn't buy it (because it was not free), after three years, Yahoo dissolved its enterprise solutions division.
Getting back to our tool, what can you do to protect yourself?
- There are a couple of software packages available, but... you must buy them.
- Try to figure out possible ways to encrypt the conversation lines. This is what I was thinking...
Features
- Encryption (decryption) of the text messages sent to (received from) your friends using Yahoo messenger.
- This initial (version 1.0) version supports only 3DES encryption algorithm.
- Encrypted messages are marked with a star (*).
- Saved messages on your HDD (messages archive) remain encrypted. The messages are decrypted as soon as you start the application.
Figure_2. Message archive.
Prerequisites
- Visual Studio 2005 Express Edition Beta 2 (or Visual Studio 2005 Team System Beta 2).
- Yahoo Messenger 7.0.
- .NET Framework 2.0 Beta Redistributable.
- A "secured whispered channel" :) to exchange the secret password with your friends (soon there will be a version available with support for key-exchange).
The pieces of the puzzle or... what are we playing with?
- Low level Windows messaging (well... now very low - just using the old WM_* messages).
- .NET cryptography.
The idea - in words
As you can see the Yahoo's messenger window is divided into several zones or areas. These zones are windows and each window has a hWnd
(Window handler). Other Windows software packages don't use this kind of technique (for example, the Office suite). Using a window handler for each control consumes the system resources. In our case, these handlers will help us achieve our goals.
The three window areas, we are interested in are:
- The area in which you are typing the message that is to be sent - WriteArea.
- The area that displays the sent/received messages from your friend - TalkArea.
- The button we click to send these messages -
SendButton
.
Figure_3. The window areas.
Next, you will see the necessary steps required to encrypt a message, to send the encrypted message and to decrypt a received encrypted message.
Sending an encrypted line of message
- Cut the message from the writing area -
hWndWriteArea
. - Encrypt it with our application.
- Paste it back, marked for decryption, into the writing area -
hWndWriteArea
. - Send it by simulating a click on the "Send" button -
hWndSendButton
Decrypting an incoming encrypted message
- Get the messages from the conversation area -
hWndTalkArea
. - Check the messages for markers.
- Decrypt the marked message.
- Paste these messages back into the conversation area -
hWndTalkArea
The idea - in code
Finding the HWNDs of the three window areas we are interested in
Check if the foreground window is a Yahoo messenger conversation window. If it's true, call MessengerYahoo_HandleWindow
method. This method moves the IMEncryptor window next to the conversation window by calling MessengerYahoo_MoveTheWindow
and then, using a delegate, it loops through the child windows to find the hWnd
s we are interested in, MessengerYahoo_HandleEnumChild
.
Tip: This function should return true
if you want to search again through the child windows and false
otherwise.
private bool MessengerYahoo_HandleEnumChild(
IntPtr hWnd, IntPtr lParam)
{
int textLength = Win32API.SendMessage(hWnd,
Win32API.WM_GETTEXTLENGTH, 0, IntPtr.Zero);
StringBuilder text = new StringBuilder(textLength + 1);
Win32API.SendMessage(hWnd, Win32API.WM_GETTEXT,
textLength + 1, text);
StringBuilder className = new StringBuilder();
Win32API.GetClassName(hWnd, className,
className.MaxCapacity);
if (className.ToString().Contains(writeAreaClassName))
hWndWriteArea = hWnd;
if (className.ToString().Contains(talkAreaContainerName))
hWndTalkArea = Win32API.FindWindowEx(hWnd,
IntPtr.Zero, talkAreaClassName, IntPtr.Zero);
if (className.ToString().Contains(sendButtonClassName))
if (text.ToString().Contains(sendButtonText))
hWndSendButton = hWnd;
if ((hWndWriteArea == IntPtr.Zero) ||
(hWndTalkArea == IntPtr.Zero) ||
(hWndSendButton == IntPtr.Zero))
return true;
else
return false;
}
writeAreaClassName
, talkAreaContainerName
, talkAreaClassName
, sendButtonClassName
and sendButtonText
are defined in the Variables
and Constants
region, at the beginning of the FrmMain
class.
#region Variables and Constants
IntPtr hWndForegroundWindow; // Foreground window handler
IntPtr hWndTalkArea; // Talk area window handler
IntPtr hWndWriteArea; // Write area window handler
IntPtr hWndSendButton; // Send button window handler
// Yahoo Messenger's window title contains this string
const String windowTitle = "- Instant Message";
// The class name of the writeArea zone
const String writeAreaClassName = "YIMInputWindow";
// The container name of the "talkArea"
const String talkAreaContainerName = "YHTMLContainer";
// The class name of the "talkArea"
const String talkAreaClassName = "Internet Explorer_Server";
// The class name of the "sendButton"
const String sendButtonClassName = "Button";
// The text of the "sendButton"
const String sendButtonText = "&Send";
// Marks the START of an encrypted line of message
const String startTag = "!%";
// Marks the END of an encrypted line of message
const String stopTag = "%!";
// This is a decrypted line
const String decryptedLineMarker = "* ";
// The secret password entered by the user
static String secretPassword;
#endregion
Sending an encrypted line of message
MessengerYahoo_HandleSend
method of the FrmMain
class deals with this issue. As you can see in the code below:
- We send
Win32Api.WM_GETTEXTLENGTH
to get the length of the text from the window behind thehWndWriteArea
andWin32Api.WM_GETTEXT
message to get the clear text message. - Initialize and use a Simetrical cryptographic provider
SIMCrypto
(3DES) by callingsc.Encrypt
to encrypt the clear text message. - Write the message back to the window behind the
hWndWriteArea
usingWin32API.WM_SETTEXT
. - Send the encrypted message, by simulating a click on the Send button (we send a
Win32API.BN_CLICK
message to the button).
Tip: Setting the foreground window back, by calling Win32API.SetForegroundWindow
, will enable the user to start typing another message.
private void MessengerYahoo_HandleSend()
{
// 1. GET the message from the writeArea
int textLength = Win32API.SendMessage(hWndWriteArea,
Win32API.WM_GETTEXTLENGTH, 0, IntPtr.Zero);
StringBuilder writingtext =
new StringBuilder(textLength + 1);
Win32API.SendMessage(hWndWriteArea,
Win32API.WM_GETTEXT, textLength + 1, writingtext);
// 2. ENCRYPT the message
SIMCrypto sc =
new SIMCrypto(SIMCrypto.ServiceProviderEnum.TripleDES);
String encryptedText = startTag +
sc.Encrypt(writingtext.ToString(), secretPassword) +
stopTag;
// Delete the message from the writeArea
Win32API.SendMessage(hWndWriteArea,
Win32API.WM_SETTEXT, 0,
System.Text.Encoding.ASCII.GetBytes("".ToCharArray()));
// 3. PASTE the new encrypted message
byte[] encryptedText_byte =
System.Text.Encoding.ASCII.GetBytes(
encryptedText.ToCharArray());
Win32API.SendMessage(hWndWriteArea,
Win32API.WM_SETTEXT, 0, encryptedText_byte);
// 4. SEND the new encrypted message
// (by simulating a click on the Send button)
Win32API.SendMessage(hWndSendButton,
Win32API.BM_CLICK, 0, encryptedText_byte);
// Delete the message from the writeArea
Win32API.SendMessage(hWndWriteArea,
Win32API.WM_SETTEXT, 0,
System.Text.Encoding.ASCII.GetBytes("".ToCharArray()));
// Set the foreground window = the messeger window
Win32API.SetForegroundWindow(hWndForegroundWindow);
}
Decrypting an incoming encrypted message
MessengerYahoo_HandleDecryption
method of the FrmMain
class deals with this issue. As you can see in the code below:
- We get a handler to the
IHTMLDocument2
by sending aWM_HTML_GETOBJECT
message to thehWndTalkArea
.IHTMLDocument2
is enclosed by the "Internet Explorer_Server" control, defined above as thetalkAreaClassName
. A small, but interesting article on this issue can be found here. - Next we are parsing its structure (in a trivial way) to get the marked messages.
- Decrypt the marked messages using the same cryptographic provider,
SIMCrypto
(3DES) and by callingsc.Decrypt
method. - Paste the decrypted message back to where it belongs.
Tip: To be able to work with IHTMLDocument2
you need to add a reference to a .NET component named Microsoft.mshtml
.
private void MessengerYahoo_HandleDecryption()
{
// 1. GET the messages from the conversation area
uint msg =
Win32API.RegisterWindowMessage("WM_HTML_GETOBJECT");
IntPtr lRes = IntPtr.Zero;
Win32API.SendMessageTimeout(hWndTalkArea, msg,
IntPtr.Zero, IntPtr.Zero,
Win32API.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
1000, out lRes);
IHTMLDocument2 myHTMLDoc =
(mshtml.IHTMLDocument2)Win32API.ObjectFromLresult(lRes,
typeof(mshtml.IHTMLDocument).GUID, IntPtr.Zero);
foreach (IHTMLElement el in (IHTMLElementCollection)myHTMLDoc.body.all)
if ((el.GetType().ToString().
CompareTo("mshtml.HTMLSpanElementClass") == 0) &&
(el.className != null))
// 2. CHECK for the markers
if ((el.innerText != null) &&
(el.innerText.IndexOf("!%") >= 0) &&
(el.innerText.LastIndexOf("%!") > 0))
{
// 3. DECRYPT the marked message
String ts = el.innerText.ToString();
String ts2 = ts.Substring(el.innerText.IndexOf(startTag) + 2,
el.innerText.LastIndexOf(stopTag) - 2);
String decryptedText = null;
try
{
SIMCrypto sc =
new SIMCrypto(SIMCrypto.ServiceProviderEnum.TripleDES);
decryptedText =
decryptedLineMarker + sc.Decrypt(ts2, secretPassword);
}
catch (Exception ex)
{
decryptedText =
"\n" + "Received a malformed encrypted string:" +
ts2 + "\n" + "Exception generated: " + ex.Message;
}
// 4. PASTE the decrypted message
el.innerText = decryptedText;
}
}
How to use IMEncryptor
- Download and install the .NET Framework 2.0 Beta 2 (if it's not already installed).
- Download and launch the IMEncryptor.exe file (you will find it as IMEncryptor_Demo.zip).
- Start IMEncryptor, enter your secret password in the text box and check the "Enable encryption" checkbox.
- Start a Yahoo Messenger conversation window. You will see that the IMEncryptor window stays next to the current conversation window.
- Type a message in the WriteArea and do not press enter after typing the message. Click on the "Send encrypted" button.
- Drop me a message (or email) if you like it or not, if you discover bugs or if you want other features to be implemented.
TODO list
- Further optimization of the code.
- Support for multiple crypto algorithms.
- Automatic key exchange mechanism.
- Management of multiple keys (for multiple users).
- Enable a global hook to capture the Enter key?
- Support for other IMs (MSN Messenger, Google Talk, ...)?
- You name the feature...
Version history
- 20.10.2005 - Version 1.0.
- The first release. Includes the main functional features.