Simple XOR Encryption
By Peter Bromberg
XOR Encryption is unique in that it is bidirectional and very simple. Sometimes the very simple is "just enough".
Even in "Intranet" environments, where the risk of hacking or "stealing" of connection strings is usually very low, nervous managers always seem to want to see connection strings either encrypted (when in a configuration file) or stored in the Registry, or "something" similar such that the plain text connection string is not easily visible to the "casual hacker".
While there is a tool for encrypting various sections of a standard .NET configuration file, it can prove to be more of an annoyance than a benefit in some situations. I've found that cautious managers can often be satisfied with simple XOR encryption, which makes things orders of magnitude easier for the developer.
Now let me just head you flamers off at the pass, so we can get on to the real issue:
1) XOR against a string of text is NOT a strong encryption algorithm. It would probably be one of the FIRST things a determined hacker would try.
2) If you do choose to use XOR, be advised that you could end up with "non XML-safe" characters.
3) If you need strong encryption, DO NOT USE XOR algorithms. OK? Rest my case.
There. Now let's get to the details. What is XOR? XOR normally stands for "Exclusive OR" and is a logical operation on two operands that results in a logical value of true if and only if exactly one of the operands has a value of true. When applied to the ASCII values of a string of text (char), it has the effect of resulting in addition with no "carry". So, if you XOR an "a" (ASCII 97) against 129, you get ASCII 224, which is an "a" character with the Accent aigue (left-pointing accent), and so on. If you choose the value that you will perform the XOR operation to each character with carefully, you can be sure to always get characters that can be placed in an XML element (your config file) without any illegal XML characters. Such a value is 129, which is what I use in this example.
In other words, every lower-case letter, upper-case letter and numeral and common symbol in the ASCII character set XOR's against 129 to result in another character that is "XML - safe" - including all the characters: !@#$%^&*()?<>/\:;"'
You can experiment with other values using the provided downloadable Visual Studio 2005 Solution and Windows Forms test harness.
In C#, we XOR one value against another like this: A ^ B
There are many variations of XOR algorithms, such as ones that use a different XOR operand for each subsequent character in the string to be "XOR-ed", but the key advantage of this algorithm is that it is symmetric. If you get a translated value by XOR-ing it against 129, and then XOR the translated value against 129, you always get back the original character's value. ALWAYS.
What that means is that you only need one method, "EncryptDecrypt". Pass a string into it and get it back encrypted. Pass the encrypted string into it and you get back the original text, as long as the XOR character is the same. The code is childishly simple:
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleXOREncryption
{
public static class EncryptorDecryptor
{
public static int key = 129;
public static string EncryptDecrypt(string textToEncrypt)
{
StringBuilder inSb = new StringBuilder(textToEncrypt);
StringBuilder outSb = new StringBuilder(textToEncrypt.Length);
char c;
for (int i = 0; i < textToEncrypt.Length; i++)
{
c = inSb[i];
c = (char)(c ^ key);
outSb.Append(c);
}
return outSb.ToString();
}
}
}This will turn this string:
server=myserver;database=mydatabase;uid=myuser;pwd=mypass;
into this:
òäó÷äó¼ìøòäó÷äóºåàõàãàòä¼ìøåàõàãàòäºôèå¼ìøôòäóºñöå¼ìøñàòòº
-- and back again, which in many cases, is "just enough" to keep things from prying eyes.
You can
download the complete solution here.
Popularity (31934 Views)
 |
| Biography - Peter Bromberg |
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
|  |
|
|
Article Discussion: Simple XOR Encryption
Jignesh replied
to Peter Bromberg at Monday, March 26, 2007 7:37 PM
Thank you sir! This was what I was looking for... I didn't want to 'marry' with Microsoft's Cryptography.. This is the best I have ever found.!
Thanks again.
Priyanka replied
to Peter Bromberg at Monday, March 26, 2007 7:37 PM
I have used your code.my requirement is that key is in sting can it posible.if yes how to do that.
When you say "key is in sting" do you mean the XOR value is to be stored in the string itself? I suppose you could tack it on to the front or the back of your phrase to be XOR-ed.
Charles replied
to Peter Bromberg at Monday, March 26, 2007 7:37 PM
Thank You Peter, I was trying all sorts of Algo's (RSA, 3DES, Blowfish etc) until I stumbled accross ur solution. Shot man. :)
Unni replied
to Charles at Monday, March 26, 2007 7:37 PM
The above algorithm is very good.The main advantage of this algorithm is there is no need of using 129 for encryption.You can use any value.For example,
public static String EncryptorDecryptor(String str) {
StringBuilder sb = new StringBuilder();
int len = (str == null) ? 0 : str.length();
char c;
for(int i = 0; i<len; i++) {
c = str.charAt(i);
c = (char)(c ^ 65);
sb.append(c);
}
return sb.toString();
}
Original Value :"<hello><employees><employee name=\"test#¤% \"></employees><hello>";
After first call, the value is })$--.}$,1-.8$$2}$,1-.8$$a/ ,$|c5$25bådaac}n$,1-.8$$2})$--.
Again calling the above method will get back the original String.
<hello><employees><employee name="test#¤% "></employees><hello>
If you call this method two times successively it will produce the original value.
This is the advantage of XOR.
sanjana replied
to Jignesh at Monday, March 26, 2007 7:37 PM
how to convert the cipher text to encrypted data. ex. if hi is the data then cipher text value with the key is 'a' then how come encrypted data is k.
h^'a' is as follows
0 1 1 0 1 0 0 0 0 1 1 0 1 0 0 1 /*binary value of hi
0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1/* ascii value of a
________________________________________
0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 /???????????????
if the value is smaller than ascii values how to convert that?
plz send me the explaination.......
Jacob replied
to sanjana at Monday, March 26, 2007 7:37 PM
If the value of the output is not displayable in normal text editors, it could be converted into a "hex" string. . .
Here is a function that converts bytes to hex string.
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}