Click here to Skip to main content
Click here to Skip to main content

A Stegano-Framework for .NET Developers

By , 2 Aug 2006
 

Introduction

This article is about turning a collection of hardly reuseable classes into a handy framework. My series of simple proof-of-concept applications and tutorial articles here on CodeProject left me with a heap of functionality. To make it useful, I have built a framework that you can plug into your applications as a black box. There also is a demo application that shows all the framework can do.

The Back End: Workers and Helpers

First I made up a list of properties and methods that all *Utility classes from the existing applications already supported, in order to define an interface from them. Then I realized that some methods (for example GetMessagePart()) appeared in several classes or were implemented somewhere else in the application. So I decided to create an abstract class FileUtility instead of an empty interface and place the common code there.

Why should an application care about which FileUtility to use? I wanted the framework to take a filename and find the right utility from the extension or content. That's what the FileType singleton is there for. It decides which type a given file is, then the concrete *FileType returns the utility object plus some information about what can be done with the carrier file. That means, a framework user retrieves a file type object and a utility object via the filename and can start hiding or extracting data right away.

The result were two base classes, each with a couple of derived classes, and a couple of specialised classes which are being used only by certain utilities. FileUtility actually is abstract. FileType does not represent a concrete type, therefor it should have been abstract, but to avoid "static dirt" I implemented it as a singleton with a few public factory methods.

SteganoDotNet.Action Class Diagram

All these classes are the namespace SteganoDotNet.Action which does the actual steganography. The other framework namespace is SteganoDotNet.UserControls; it makes the configuration of carriers comfortable, but it's not essential. For example, with the Action namespace it is possible to waterwark a song without telling the framework that it's a standard MIDI file:

string originalFileName = @"C:\Somewhere\music.mid";
string resultFileName = @"C:\Somewhere\result.mid";

FileType fileType = FileType.Current.GetFileType(originalFileName);
FileUtility fileUtility = fileType.CreateUtility(originalFileName);
fileUtility.CountBytesToHide = watermarkText.Length;
fileUtility.CountUsedBitsPerUnit = watermarkText.Length/fileUtility.CountUnits;
fileUtility.OutputFileName = resultFileName;

using (Stream message = streamboxMessage.Stream)
{
 Stream formattedMessage = fileUtility.GetMessagePart(message);
 fileUtility.Hide(formattedMessage, new MemoryStream());
}

The Front End: Forms and Boxes

Every file utility needs some basic information like input data stream (not every carrier must be stored in a file!), and output file name. Depending on the file type's stegano-abilities, additional properties need to be configured. For example, a bitmap file utility has to know which regions of the image to use, or a wave file utility needs the count of bits to change per sample. But don't worry, a framework user does not need to know everything about every file type: The namespace SteganoDotNet.UserControls contains GUI parts for every kind of carrier. You don't even have to choose which control to use. Every FileUtility has got a property CarrierConfigurationControl which returns a UserControl with a complete configuration GUI. That control raises the event CancelSettings, when the user cancels the configuration and the file utility is not ready to hide data. When the user has entered and confirmed all settings, the file utility raises its SettingsChanged event.

The following example creates a FileUtility for a bitmap and displays the configuration control. If the user clicks the control's cancel button, the control gets removed and nothing happens. If the apply button is clicked instead, FileUtility_SettingsChanged embeds a message in the bitmap. All configuration information like output file name, whether or not to add random noise, the image regions to use, are collected by the CarrierConfigurationControl. As long as you don't have any cool ideas about the perfect carrier configuration GUI, you can rely on the framework instead of messing with the forms designer.

FileUtility fileUtility = <BR>          BitmapFileType.Current.CreateUtility(@"C:\Somewhere\original.tif");
fileUtility.SettingsChanged += new EventHandler(fileUtility_SettingsChanged);
fileUtility.CarrierConfigurationControl.CancelSettings += <BR>                                     new EventHandler(config_CancelSettings);
fileUtility.CarrierConfigurationControl.ExpectedMessageLength = <BR>                                                     sbMessage.Stream.Length;
((BitmapConfiguration)<BR>             fileUtility.CarrierConfigurationControl).PercentOfMessage = 100;
panelConfig.Controls.Add(fileUtility.CarrierConfigurationControl);

[...]

private void CarrierConfiguration_CancelSettings(object sender, EventArgs e)
{
    panelConfig.Controls.Remove(fileUtility.CarrierConfigurationControl);
}

private void FileUtility_SettingsChanged(object sender, EventArgs e)
{
    FileUtility fileUtility = (FileUtility)sender;
    panelConfig.Controls.Remove(fileUtility.CarrierConfigurationControl);
    Stream fullMessage = fileUtility.GetMessagePart(message);
    fileUtility.Hide(fullMessage, sbKey.Stream);
    fullMessage.Dispose();
}

The prefix sb in sbMessage.Stream stands for StreamBox. This little control encapsulates a GUI part that I needed quite often. No matter how the user decides to enter a piece of content, by filename or plain text, the StreamBox returns the content as a Stream.

StreamBox control

Lossy Sound: The End of Comfortable Controls

The FileType/FileUtility/CarrierConfiguration architecture worked fine for all carrier types, except for the loss resistant audio stuff. I wanted to keep the framework free from third party components, but without support for reading/writing audio discs, the GUI would not seem complete. That's why TapeWaveFileUtility.CarrierConfiguration returns a TapeWaveConfiguration, but as soon as you place it on a form, the utility raises its OpenTapeForm event. Then the application has to show its own modal configuration dialog and copy the settings into the file utility. Take a look at WaveHideForm in the demo application for a complete example. That form reads tracks from an audio disc, allows you to configure each track in a dialog you might know from an older article ^, distributes a message over these audio tracks and finally burns a new audio CD. WaveExtractForm also reads tracks from an audio CD, then it shows a quite equal configuration dialog to make TapeWaveFileUtility find the frequency markers:

TapeForm dialog

Those wave processing dialogs are so complex and user-unfriendly that they did not become parts of the framework. The task of filtering the wave with a bandpass filter before calling TapeWaveUtility.FindAnything() is up to the application itself. FindAnything() is the first step of data extraction: It finds the frequency markers. The application is informed about every single Beep with the BeepFound event. In the demo, WaveDisplayControl handles those callbacks to give the user a last chance for manual corrections (which means, removing false positives). Finally, WaveExtractForm uses the (maybe manually fixed) result to fill TapeWaveFileUtility.Seconds and extract the actual message.

I assume you have not read the entire last preceding paragraph. You're right. Preparing a wave for message extraction is a little too complicated and I'll try to make things easier in the next version. Until then, I suggest you copy TapeForm and WaveDisplayControl into your own application, if you want to use loss resistant audio steganography.

Back to the Roots

At this point, I had a useful framework and a huge demo application which I called S4U (Steganography for You). I presented it as my exam project at evening school and got top grades. Then school was over and I had too much spare time. Why not turn the whole thing into an open source project? Nice idea, but three components I integrated for audio features are not published under GPL: The wave recorder^ and the CD ripper^ are samples from CodeProject, Steve McMahon's IMAPI-Wrapper ^ is a Creative Commons library.

I did not really solve that problem. That means, i did - if you call deletion of features a solution. When I had removed all CD ripping/burning and wave live recording dialogs, the framework and the demo application were free from third party code. Both still call Sound Exchange^, but this one is not compiled into or referenced by my assemblies, and anyway, it is GPL software.

Now that my steganography framework was ready to become a GPL licensed open source project, I needed a version control system, a bug tracker, a place for documentation, releases, forums and feature request ... in short words: I registered a SourceForge^ account and a project called SteganoDotNet^. The next day my project was accepted and I could check in all my files. Well, that's the way my steganography tutorials will go from now on: You have great ideas? Come to SourceForge and code them into the framework! Especially I'd be very happy about anybody who added JPEG support, or a new audio CD ripper/recorder ... welcome to my first open source project, feel free to join and make it the stegano-framework for the .NET world. :-)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Corinna John
Software Developer
Germany Germany
Corinna lives in Hannover/Germany (CeBIT City) and works as a Delphi developer, though her favorite language is C#.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralLooks good.memberxjli6-Nov-08 12:20 
Looks great and might be what I am looking for.
Acctually I am looking for codes to do highpass filter on WAV files. Too bad I am using an old version .NET environment and couldn't open your project to try it. Smile | :) Confused | :confused:
GeneralRe: Looks good.memberCorinna John7-Nov-08 7:03 
I'm sorry to tell you that this projects calls Sound eXchange[^] for high-/lowpass filters. There's no .NET implementation in here. Wink | ;)
 
This statement is false.

GeneralGood Article!memberChris S Kaiser9-Aug-06 8:26 
Hi Corinna,
 
I'm curious about the different uses of stego in audio, beyond watermarking (not sure if you meant to use waterwark above), what types of uses do you visualize for this? I can see embedding format info for various players and the like, and maybe for copy protection, but am curious to hear more. Particularly I'm interested in how this can be used for games.
 
Does your work encompass other music based programming?
 
Thanks for the great work!
 
This statement is false.

GeneralRe: Good Article!memberCorinna John11-Aug-06 13:36 
Usually I have rather strange ideas about use cases... The idea behind the loss-resistant audio part was to hide additional information in broacasts or on tape. You could broadcast secret data in an innocent radio show or transfer hidden information to insiders by playing a record in a crowded room.
Not realistic, but funny and mysterious... Roll eyes | :rolleyes:
 
Music based programming is not my area of expertise, it contains too much math. But I do some experiments with waves sometimes, you might have a look at this toy:
Compose sounds from frequencies and visualize them
 

____________________________________
There is no proof for this sentence.

GeneralRe: Good Article!memberChris S Kaiser11-Aug-06 14:35 
Corinna John wrote:
you might have a look at this toy:

 
Sweet.. this would be nice to use for a visual effect during a stage show.
 
This statement is false.

GeneralShe is cute.... [modified]memberMarc Leger4-Aug-06 6:11 
and there are entirely too many hollier-than-thou Republicans on this board.
 
I found DiscReader and DisBurner to be of great help on my current project. Thanks for the post.
 
- TechnoPop
GeneralGreat !memberNinjaCross3-Aug-06 2:45 
Thankyou so much for posting your work.
I found so usefull your ILFileType / ILFileUtility classes and related components.
Maybe you could use them to build a demo steganography utility for .NET assemblies... but probably you have already do it Wink | ;)
 
--
NinjaCross
www.ninjacross.com

QuestionGPL = useless licensememberloizzi2-Aug-06 19:45 
Hello,
 
I already read some articles from you but this is the best. Sadly you decided for the useless GPL license so I can't use this framework for commercial applications. How about the LGPL?
 
Die meisten Quellen sind hier entweder frei oder unter der LGPL, GPL ist eher was für open source Apostel... Roll eyes | :rolleyes:
 
Ciao
 
Frank Loizzi
Dortmund
Germany
Answeruseless for you, protection for mememberCorinna John2-Aug-06 19:56 
Hallo Frank,
 
you considered using it in a commercial app? You wanted to make money from my free work?! That's lazy of you, is it? Roll eyes | :rolleyes:
 
It's your right to analyse the code, learn from it, write your own library and then sell it. But you won't make your customers pay for code I gave you for free. That's my reason for GPL. Poke tongue | ;-P

GeneralRe: useless for you, protection for mememberloizzi2-Aug-06 20:47 
Hallo Corinna,
 
I do not want sell your code, I only want to use it in a commercial application for copy protection purpose. So I want use it in the manner of its state of aggregation, as library. I don't talk about selling your library as Stegano-Framework.dll.
 
Bye
 
Frank Loizzi
Dortmund
Germany
 

GeneralRe: useless for you, protection for mememberCorinna John3-Aug-06 1:23 
Hey Frank,
 
as I found out, you actually can use GPL licensed components in commercial software. You only cannot use it in closed source software. If you ship the source code with every copy of your application, it's perfectly fine. The only problem you might run into is that the users are allowed to copy the application and give it to other people who would otherwise have to buy it from you.
 
Look here: http://www.gnu.org/philosophy/free-sw.html[^]
 
"A program is free software if users have all of these freedoms. Thus, you should be free to redistribute copies, either with or without modifications, either gratis or charging a fee for distribution"
 
That means, you may charge a fee for your free program.
 
"You should also have the freedom to make modifications and use them privately in your own work or play, without even mentioning that they exist."
 
Ain't that great? You can even enhance the framework to make it embed real StirMark-safe watermarks! (Usually it creates LSB messages, that's not good for copyright protection...)
 
"You may have paid money to get copies of free software, or you may have obtained copies at no charge. But regardless of how you got your copies, you always have the freedom to copy and change the software, even to sell copies.
'Free software' does not mean 'non-commercial'. A free program must be available for commercial use, commercial development, and commercial distribution. Commercial development of free software is no longer unusual; such free commercial software is very important.
"
 
I couldn't have said it in better words.
 
"The freedom to redistribute copies must include binary or executable forms of the program, as well as source code, for both modified and unmodified versions."
 
Yes, your commercial application must be distributed with source code. Anyway, you may also charge some money that that process (and for the CD, for the service, for ... )
Look at SUSE Linux: Novell earns money by selling distributions, even though every customer can copy his copy. It actually seems to work. Smile | :)
 
Have Fun
coco
 

 

GeneralRe: useless for you, protection for mememberloizzi3-Aug-06 4:25 
Hallo Corinna,
 
thanks for the explanations but I already knew about the meaning of GPL license. Thats the reason why I wrote GPL = useless license. You have to deliver your source with your software and I can't do that, because the source is my intellectual property and that is the only reason why I can sell software. If I deliver my work with my applications I deliver my work to thousands of plagiarist and there is no more to sell. Smile | :)
 
Furthermore I can't deliver source code from libraries that are closed source and which I bought and which I use in the same application. So the GPL license is a very useless license, thats the reason why mainly the LGPL license is used. What about your problem with the LGPL license?
 
My target group is the private customer not the industrial audience. So I can't provide only support services and live from that. I have to make money to pay my bills like any other.
 
If you don't change your mind, I unfortunately can't use your work. But it is indeed a nice article and you are indeed cute as a button. Wink | ;-)
 
Grüße aus Dortmund...
 
Frank Loizzi
Dortmund
Germany
GeneralRe: useless for you, protection for mememberJohn Rayner3-Aug-06 8:38 
loizzi wrote:
If I deliver my work with my applications I deliver my work to thousands of plagiarist and there is no more to sell

 
Don't you think that's a bit rich? You're trying to use someone else's source code for free, but you don't want other people to use your work for free. It's more than a little bit hypocritical.
 
loizzi wrote:
My target group is the private customer

 
This means that they will generally not know how to program. In other words, they are unlikely to actually do anything with your source code.
AnswerRe: useless for you, protection for mememberloizzi3-Aug-06 10:33 
John Rayner wrote:
loizzi wrote:
If I deliver my work with my applications I deliver my work to thousands of plagiarist and there is no more to sell
 
Don't you think that's a bit rich? You're trying to use someone else's source code for free, but you don't want other people to use your work for free. It's more than a little bit hypocritical.

 
Yes. So what? I really don't understand what you mean? Do you know SourceForge or even Codeproject? Do you think this is a source stock exchange? Most projects exist for fun, for learning purpose, for beta testing and so on. Can you explain whats exactly your problem?
 
loizzi wrote:
My target group is the private customer
 
John Rayner wrote:
This means that they will generally not know how to program. In other words, they are unlikely to actually do anything with your source code.

 
Thats simple-hearted. Do you really think that? First (I guess you have not read my post exactly) every competitor is able to produce an own version of my work. Thats something really bad. Dead | X|
 
Second, there is a massive security problem for people they do nothing (like you said) with the source code.
 
And finally I have no motivation to produce sophisticated software if I can't earn money from this work.
 
I don't want to discuss this anymore, because this is to self-evident and I don't depending on this framework. So I simply work for my own or look for another project.
 
Bye
 
Frank Loizzi
Dortmund
Germany
 

GeneralWhat about a second license?memberttoni664-Aug-06 2:08 
So, why don't you offer Corinna some money to give her code to you under some other license, like LGPL or something even more commercial? A lot of free software projects do this and it seems quite sensible to me. Both sides win.
AnswerRe: What about a second license?memberloizzi4-Aug-06 2:57 
Hello,
 
yes, you are right. But I don't essentially need her framework to build applications. It would only be a nice extension to some kind of application. So I have no motivation to pay for it. Mainly I was simply telling her that the GPL license is a kind of viral license and has nothing to do with freedom or protection. Unfortunately she isn't telling us whats wrong with the LGPL and what kind of protection offers the ideological GPL license for her. So I think she has decided to stop responding and I look for something different.
 
Bye
 
Frank Loizzi
Dortmund
Germany
GeneralRe: What about a second license?memberlolocmwa15-Aug-06 23:46 
So no motivation to pay for it ! But still motivation to get paid for it ? Indeed you lose so much time to get something free, maybe we shoud pay you to help you getting what you want Smile | :)
 


GeneralRe: What about a second license?memberCorinna John16-Aug-06 4:40 
As I understand him, we should pay him for getting paid. Roll eyes | :rolleyes:
 

____________________________________
There is no proof for this sentence.

JokeRe: What about a second license?memberCPallini15-Nov-07 5:50 
loizzi wrote:
I was simply telling her that the GPL license is a kind of viral license and has nothing to do with freedom or protection

 
Tell it to those guys [^] too. They do not seem aware about Big Grin | :-D
 
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.

GeneralRe: What about a second license?memberMember 52080816-Jan-09 8:53 
Basically LGPL is better in the sense that if we make it LGPL lot of commercial products can have it and it becomes more popular and so lot of groups will use it. Out of them say even 10% give back to society then overall the library gets improvements and contributions from outside. If its made GPL then the motivation to work on it from commercial usage is nil and so will only be contributed by non commercial research groups etc. So overall LPGL is more flexible and improves the framework as the users have more options. Of course there are people who use it but not contribute back but that is fine compared to the other advantages.
GeneralRe: What about a second license?memberCorinna John16-Jan-09 9:10 
Show me one commercial group that would consider using such simple stego! Then I'll make it LGPL. Rose | [Rose]
As long as the framework's quality is only for students and nerds, I'm sure that GPL is enough.
 
This statement is false.

Generalyour a cutie !memberVarindir Rajesh Mahdihar2-Aug-06 10:15 
Blush | :O
GeneralRe: your a cutie !memberDustin Metzgar2-Aug-06 10:35 
Wow. Here's an article describing Corinna's steganography framework, which is something she obviously put a lot of time and effort into. She's shown herself time and again to be a respectable and professional programmer. And in one sentence you've managed to disregard all her hard work and belittle her.
 


Logifusion[^]
If not entertaining, write your Congressman.
GeneralRe: your a cutie !memberCorinna John2-Aug-06 10:41 
Hi Dustin!
 
Let's calm down and ignore that guy. Wink | ;)
 
Dustin Metzgar wrote:
put a lot of time and effort into

 
It was approximately one year, but I didn't work on it continuously, only on every second or third weekend and one summer vacation. Cool | :cool:
GeneralRe: your a cutie !memberttoni664-Aug-06 2:09 
Umm, whats wrong with being a respected developer *and* being cute? I find myself quite cute, too Poke tongue | ;-P
 
And before anyone jumps to false conclusions: The number at the end of my nick is actually my birth-year Smile | :)
GeneralRe: your a cutie !memberreinux1-Jan-07 22:28 
Woah "you're a cutie" is a belittling remark?! I thought he just said that sorta as an aside!
 
Not much reason to get defensive no?
 
Man, CP drama is weird sometimes Laugh | :laugh:
GeneralRe: your a cutie !memberGrav-Vt4-Aug-06 4:07 
Err - so now it is an insult to acknowledge another as attractive; let's drop the opinion policing Mad | :mad: and recognize that simply every post she makes is brilliant and aside from that another poster has complimented her for something other than code.
GeneralRe: your a cutie !memberCorinna John4-Aug-06 5:27 
Grav-Vt wrote:
now it is an insult to acknowledge another as attractive

 
Definitley not, but in this context it's rather strange:
You post a .NET library an the first comment you get is "[I don't care about software, but] the photo in your profile looks cute". Such a statement looks ignorant, even though the author meant it as a nice compliment.
 
Grav-Vt wrote:
simply every post she makes is brilliant

 
Thanks Blush | :O
 
Have a nice weekend
coco

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 2 Aug 2006
Article Copyright 2006 by Corinna John
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid