Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Steganography in Windows Phone

From Wiki
Jump to: navigation, search

This article demonstrates how to implement steganography in Windows Phone, hiding text inside an image retrieved from the gallery.

WP Metro Icon File.png
WP Metro Icon Multimedia.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleTested with
Devices(s): Nokia Lumia 820, Lumia 920
Compatibility
Platform(s): Windows Phone 7.1 and later
Windows Phone 8
Windows Phone 7.5
Platform Security
Signing Required: Self-Signed
Capabilities: ID_CAP_MEDIALIB_PHOTO
Article
Keywords: Steganography
Created: somnathbanik (05 Apr 2013)
Last edited: hamishwillee (17 Jul 2013)

Contents

Introduction

Steganography is the art/science of hiding a message in such a way that it isn't obvious to anyone other than the sender/receiver that there is a message present. In this article we will use steganographic techniques to encode text messages inside an image taken from the picture hub, without significantly changing the appearance of the original image.

Note.pngNote: The wiki article Stegafoto: a lens which embeds audio and text inside images encodes data into captured image as it is taken using the camera (via a lens) rather than using an image from the gallery as described in this article. Both articles use the same approach, albeit with slightly different implementations of the algorithm. The explanation in this article is less detailed but also more succinct.


Algorithm

To store the text data we encode it in the "least significant bit" across a number of bytes of image data. Each bit that is changed will affect the value of the whole encoded byte by at most "one", a change which will be virtually undetectable when viewing the image. In order to identify which bytes contain information, we first encode the length of the data to be stored before the rest of the message (in variable Threshold).

To iterate through the text data we simply right/left shift the data in each byte as required (for encoding and decoding). The code fragments below show this process (which is easier to view in code than explain).

Implementation

Create a standard Windows Phone Project

Let’s create a standard Windows Phone Application Project

  • Launch Visual Studio
  • Click on File
  • Click on New Project
  • Select Windows Phone Pivot Application (Visual C# Template)
  • Add Name and Location of the project
  • Click OK to create the project.

Adding UI controls on application page

We have two PivotItem one for encoding and other for decoding text message. In the project, double-click the MainPage.xaml file and add the below code in root element.

<!--Pivot Control-->
<phone:Pivot Title="STEGANOGRAPHY">
<!--Pivot item one-->
<phone:PivotItem Header="encode">
<StackPanel Orientation="Vertical" Margin="0,0,0,0">
<Image Stretch="UniformToFill" Name="ImageEncode" HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="456" />
<Button Name="ButtonSelectImage" Content="Select Image" Click="ButtonSelectImage_Click" />
<TextBox Name="TextBoxEncode" InputScope="Text" Height="72" TextWrapping="Wrap" Text=""/>
<Button Content="Encode Text" Click="Button_Click_1" />
</StackPanel>
</phone:PivotItem>
 
<!--Pivot item two-->
<phone:PivotItem Header="decode ">
<StackPanel Orientation="Vertical" Margin="0,0,0,0">
<Image Stretch="UniformToFill" Name="ImageDecode" HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="456" />
<Button Content="Select Image" Click="Button_Click_2"/>
<Button Content="Decode Text" Click="Button_Click_3"/>
<TextBlock TextWrapping="Wrap" Text="Decoded Text :" Margin="10,0" Height="35"/>
<TextBlock Name="TextBlockDecodeText" Foreground="Red" TextWrapping="Wrap" Text="" FontSize="30" RenderTransformOrigin="0.543,0.736" Margin="10,0" Height="58"/>
</StackPanel>
</phone:PivotItem>
</phone:Pivot>

Encoding text message into image

  • Open the MainPage.xaml.cs file and add the following namespaces:
using System.IO;
using System.Text;
using Microsoft.Phone.Tasks;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Media;
  • Add the following declarations to the MainPage class:
PhotoChooserTask photoChooserTaskEncode;
PhotoChooserTask photoChooserTaskDecode;
Stream capturedImageEncode, capturedImageDecode;
public byte[] byteArrayInputImageEncode { get; set; }
public byte[] byteArrayInputText { get; set; }
public byte[] byteArrayInputImageDecode { get; set; }
private byte[] byteArrayTextandImage { get; set; }
public int textLength = 4096;
  • Add the following initialization in the MainPage constructor:
// Constructor
public MainPage()
{
InitializeComponent();
photoChooserTaskEncode = new PhotoChooserTask();
photoChooserTaskEncode.Completed += photoChooserTaskEncode_Completed;
photoChooserTaskDecode = new PhotoChooserTask();
photoChooserTaskDecode.Completed += photoChooserTaskDecode_Completed;
}

This will initialize the PhotoChooserTask and will call the photoChooserTaskEncode_Completed and photoChooserTaskDecode_Completed event when the image is selected from the picture hub.

  • Add the following photoChooserTaskEncode_Completed and photoChooserTaskDecode_Completed method to the MainPage class:
void photoChooserTaskDecode_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
capturedImageDecode = e.ChosenPhoto;
BitmapImage bmp = new BitmapImage();
bmp.SetSource(capturedImageDecode);
ImageDecode.Source = bmp;
byteArrayInputImageDecode = ReadToEnd(capturedImageDecode);
}
else
{
MessageBox.Show("Unable to select photo");
}
}
 
void photoChooserTaskEncode_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
capturedImageEncode = e.ChosenPhoto;
BitmapImage bmp = new BitmapImage();
bmp.SetSource(capturedImageEncode);
ImageEncode.Source = bmp;
byteArrayInputImageEncode = ReadToEnd(capturedImageEncode);
}
else
{
MessageBox.Show("Unable to select photo");
}
}

photoChooserTaskEncode_Completed and photoChooserTaskDecode_Completed events will be called when user selects an image from the picture hub and display the selected picture in an Image element. ReadToEnd() method converts image stream to byte array.

  • Add the following code inside a Button event to encode the text message in the selected image and save the encrypted image in the Media Library:
//encode text button
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string inputText = TextBoxEncode.Text + "#";
byteArrayInputText = Encoding.UTF8.GetBytes(inputText);
textLength = byteArrayInputText.Length;
try
{
byteArrayTextandImage = EncodeText(byteArrayInputImageEncode, byteArrayInputText, 4096);
}
catch (Exception ex)
{
}
MediaLibrary library = new MediaLibrary();
try
{
Picture pic = library.SavePicture(Guid.NewGuid().ToString(), byteArrayTextandImage);
MessageBox.Show("Your picture is now accessible through the Saved Picture album.", "Saved successfully.", MessageBoxButton.OK);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
 
private byte[] EncodeText(byte[] Image, byte[] Text, int Threshold)
{
for (int i = 0; i < Text.Length; ++i)
{
int chr = Text[i];
for (int j = 7; j >= 0; --j, ++Threshold)
{
int b = (chr >> j) & 1;
Image[Threshold] = (byte)((Image[Threshold] & 0xFE) | b);
}
}
return Image;
}

Decoding text message from the encrypted image

Add the following code to decode the text message from the selected encrypted image and display on the screen.

private void Button_Click_3(object sender, RoutedEventArgs e)
{
byte[] decodedText = DecodeText(byteArrayInputImageDecode);
string text = Encoding.UTF8.GetString(decodedText, 0, decodedText.Length);
string[] split = text.Split(new Char[] { '#' });
text = split.GetValue(0).ToString();
TextBlockDecodeText.Text = text;
}
private byte[] DecodeText(byte[] Image)
{
int length = 0;
int Threshold = 4096;
for (int i = 0; i < 4096; ++i)
{
length = (length << 1) | (Image[i] & 1);
}
byte[] decodedText = new byte[textLength];
for (int j = 0; j < decodedText.Length; ++j)
{
for (int k = 0; k < 8; ++k, ++Threshold)
{
decodedText[j] = (byte)((decodedText[j] << 1) | (Image[Threshold] & 1));
}
}
return decodedText;
}

Summary

This example uses a basic approach of steganography which demonstrates with an image and a text message. It can also be done with audio/video. To make this example more user attractive you can also take picture from camera and add your text message in it.


Source Code

This page was last modified on 17 July 2013, at 11:05.
305 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×