On 6 Aug 2006 18:40:27 -0700,
ff******@gmail. com wrote:
>I need to create a method for a web page I'm building that encrypts a
number from 1 to 1000 into a 4 digit hex code. I know nothing about
cryptography . Can anyone steer me in the right direction?
Some observations:
1 You will never get a great deal of security if you are encrypting
such a small range of numbers. All an attacker has to do is to try
each possible number and see if it works.
2 All the cyphers in .NET (Rijndael, DES, 3DES, RC2) are block cyphers
so unless you are careful your 4 digits will be padded to the size of
a block (8 bytes or 16 bytes).
3 You don't say if you are going to hard code your encryption into
your code or if you are going to be changing the key on a regular
basis. If you want a simple way to hard code things then see below.
4 If you want to change the key then my suggestion would be to use a
stream cipher, or else a block cypher in counter (CTR) mode. Given
that .NET does not seem to have an easy way to operate its cyphers in
CTR mode, then you best bet is to use RC4 which is a stream cipher.
RC4 is a bit old and not very secure, but you are never going to get a
lot of security anyway given the limited range of numbers you are
encrypting. The big advantage of RC4 is that it is absurdly easy to
program. As it is a stream cipher it will not expand your plaintext
beyond four bytes. If you do decide to use a block cipher then use
Rijndael, also known as AES, in CTR mode.
5 You should read up a little on cryptography. Wikipedia is very good
on this. Articles I suggest are:
Block cipher:
http://en.wikipedia.org/wiki/Block_cipher
Stream cipher:
http://en.wikipedia.org/wiki/Stream_cipher
Block cipher modes:
http://en.wikipedia.org/wiki/Block_c...s_of_operation
RC4:
http://en.wikipedia.org/wiki/RC4
Rijndael/AES:
http://en.wikipedia.org/wiki/Advance...ption_Standard
6 Simple Hard Coding
This is a Vigenère cypher,
(
http://en.wikipedia.org/wiki/Vigenère_cipher) which is enough to
deter casual readers, but is not in any real sense secure - a given
digit in a given position will always have the same cyphertext. Note
also that anything to do with security needs more error checking than
most other code.
// Code ----------------------------------
static string chars =
"qwe5rtyu6iopl4 kjhg7fdsa3zxcv8 bnmQ2AZXS9WEDCV 1FRTGB0NHYUJMKI OLP";
static int charLen = chars.Length;
static int ptMin = 1; // Minimum value of plaintext
static int ptMax = 1000; // Maximum value of plaintext
static int ptDigits = 4; // Number of digits in plaintext
static string dummy = "0000"; // Same length as plaintext
// Offsets is the key to the encryption,
// any four numbers in the range 1 to 61 inclusive.
static int[] offsets = { 34, 60, 18, 3 };
//----------------------------------------
static void Main() {
const int numTests = 20;
Random rand = new Random();
int pText1, pText2;
String cText;
for (int i = 0; i < numTests; ++i) {
pText1 = 1 + rand.Next() % 1000;
Console.Write(" Plaintext: {0:0000}", pText1);
cText = Encypher(pText1 );
Console.Write(" \tcyphertext: {0}", cText);
pText2 = Decypher(cText) ;
Console.Write(" \tplaintext2: {0:0000}", pText2);
if (pText1 != pText2) {
Console.WriteLi ne("\tFailed!") ;
} else {
Console.WriteLi ne("\tOK");
} // end if
} // end for
Console.Write(" Press Enter to continue... ");
Console.ReadLin e();
}
//----------------------------------------
static string Encypher(int plaintext) {
if (plaintext < ptMin || plaintext ptMax) {
throw new ArgumentExcepti on("Encypher: plaintext value
incorrect.");
} // end if
StringBuilder pText = new
StringBuilder(p laintext.ToStri ng(dummy));
StringBuilder cText = new StringBuilder(d ummy);
for (int i = 0; i < ptDigits; ++i) {
cText[i] = chars[(CharVal(pText[i]) + offsets[i]) %
chars.Length];
} // end for
return cText.ToString( );
} // end Encypher()
//----------------------------------------
static int Decypher(string cyphertext) {
if (cyphertext == null) {
throw new ArgumentNullExc eption("Decyphe r: null cyphertext.");
} // end if
if (cyphertext.Len gth != ptDigits) {
throw new ArgumentExcepti on("Decypher: cyphertext is the wrong
length.");
} // end if
StringBuilder pText = new StringBuilder(d ummy);
for (int i = 0; i < ptDigits; ++i) {
// Add extra charLen to avoid negatives
pText[i] = chars[(CharVal(cypher text[i]) - offsets[i] +
charLen) % charLen];
} // end for
int retVal = Convert.ToInt32 (pText.ToString ());
if (retVal < ptMin || retVal ptMax) {
throw new ApplicationExce ption("Decypher : return value
incorrect.");
} // end if
return retVal;
} // end Decypher()
//----------------------------------------
static int CharVal(char target) {
return chars.IndexOf(t arget);
} // end CharVal()
// End Code ------------------------------
HTH
rossum