By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,189 Members | 2,167 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,189 IT Pros & Developers. It's quick & easy.

Mission: Difficult [encrypt/obfuscate 9-digit SSN into 20 chars or less]

P: n/a
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or
less?? Maybe I'm overthinking the problem somehow?
Nov 16 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
I guess ROT[BASE] is to simple?

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to
create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars
or
less?? Maybe I'm overthinking the problem somehow?

Nov 16 '05 #2

P: n/a
Drebin,

You could always use the MD5 hash algorithm (using the MD5 class or the
MD5CryptoProvider in the System.Security.Cryptography namespace. This will
produce a 128 bit hash code, which you can store in 8 unicode characters.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to
create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars
or
less?? Maybe I'm overthinking the problem somehow?

Nov 16 '05 #3

P: n/a
I've done this before: randomly generate a one-time pad each type you need
to encrypt, use it to encrypt your characters, break up the pad into single
characters and stick it inside the encrypted string along with dummy
characters. Your decryption code will know the pad and what to decrypt. You
can vary this by changing the order of the pad and/or the data, by using
other dummy values. It all depends on how secure you need to be.

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or less?? Maybe I'm overthinking the problem somehow?

Nov 16 '05 #4

P: n/a
Drebin <th*******@hotmail.com> wrote:
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or
less?? Maybe I'm overthinking the problem somehow?


Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?

DES will encrypt 5 bytes (or more easily, 8 bytes) into 8 bytes, and
then you could use base-64 to go from that to a 12 character form.

Here's some sample code to do just that. Note that it will encrypt
"000123" in the same way as "00123" (and decrypt them both as "123").
If that's a problem, you'll need to think of a slightly different way
of going from the ID to a long, but I'm sure it'll be doable.
using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
static void Main()
{
// In real code you'd need to set an IV and Key to be the same
// thing each time, of course
DESCryptoServiceProvider csp = new DESCryptoServiceProvider();
string encrypted = Encrypt (csp, "123456789");

Console.WriteLine ("Encrypted version: {0}", encrypted);

string plain = Decrypt (csp, encrypted);
Console.WriteLine ("Plain text: {0}", plain);
}

static string Encrypt(DESCryptoServiceProvider csp, string plain)
{
long number = long.Parse(plain);
byte[] bytes = BitConverter.GetBytes(number);
ICryptoTransform trans = csp.CreateEncryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.Close();
}

return Convert.ToBase64String (ms.ToArray());
}
}

static string Decrypt (DESCryptoServiceProvider csp,
string encrypted)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);

ICryptoTransform trans = csp.CreateDecryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(encryptedBytes, 0, encryptedBytes.Length);
cs.Close();
}

byte[] decryptedBytes = ms.ToArray();
if (decryptedBytes.Length != 8)
{
throw new ArgumentException ("encrypted",
"Invalid data");
}
return BitConverter.ToInt64(decryptedBytes, 0).ToString();
}
}
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #5

P: n/a
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
You could always use the MD5 hash algorithm (using the MD5 class or the
MD5CryptoProvider in the System.Security.Cryptography namespace. This will
produce a 128 bit hash code, which you can store in 8 unicode characters.


It won't be definitely unique though... Admittedly the chances of it
not being unique are tiny, but using a two-way scheme guarantees
uniqueness here.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #6

P: n/a
See inline...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Drebin <th*******@hotmail.com> wrote:
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21 characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or less?? Maybe I'm overthinking the problem somehow?
Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?


This is in a database, and then the 20 chars we're send are in an XML doc -
so assume everything is CHARACTERS.

These are standard U.S. social security numbers, so yes - nine digits that
are 0 through 9. What do you mean representable as 5 bytes??
DES will encrypt 5 bytes (or more easily, 8 bytes) into 8 bytes, and
then you could use base-64 to go from that to a 12 character form.

Here's some sample code to do just that. Note that it will encrypt
"000123" in the same way as "00123" (and decrypt them both as "123").
If that's a problem, you'll need to think of a slightly different way
of going from the ID to a long, but I'm sure it'll be doable.

Lemme take a look at this... thanks much!!
using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
static void Main()
{
// In real code you'd need to set an IV and Key to be the same
// thing each time, of course
DESCryptoServiceProvider csp = new DESCryptoServiceProvider();
string encrypted = Encrypt (csp, "123456789");

Console.WriteLine ("Encrypted version: {0}", encrypted);

string plain = Decrypt (csp, encrypted);
Console.WriteLine ("Plain text: {0}", plain);
}

static string Encrypt(DESCryptoServiceProvider csp, string plain)
{
long number = long.Parse(plain);
byte[] bytes = BitConverter.GetBytes(number);
ICryptoTransform trans = csp.CreateEncryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.Close();
}

return Convert.ToBase64String (ms.ToArray());
}
}

static string Decrypt (DESCryptoServiceProvider csp,
string encrypted)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);

ICryptoTransform trans = csp.CreateDecryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(encryptedBytes, 0, encryptedBytes.Length);
cs.Close();
}

byte[] decryptedBytes = ms.ToArray();
if (decryptedBytes.Length != 8)
{
throw new ArgumentException ("encrypted",
"Invalid data");
}
return BitConverter.ToInt64(decryptedBytes, 0).ToString();
}
}
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #7

P: n/a
Well, it's not necessarily bad - but when this vendor (although it's a
trusted vendor) sees a bunch of (for example, 5 SSN's that start with "011"
for example)

aab******
aab******
aab******
aab******
aab******

type records, they will know it's basically a character replacement.. and
again, they are a trusted vendor, but we'd rather not have our SSN's or an
easily-discoverable version of their SSN available to them.

Thanks though

"Dennis Myrén" <de****@oslokb.no> wrote in message
news:5t******************@news2.e.nsc.no...
I guess ROT[BASE] is to simple?

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21 characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to
create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars
or
less?? Maybe I'm overthinking the problem somehow?


Nov 16 '05 #8

P: n/a
Jon,

Thanks for your help, but this is what I ran into before (regarding your
code below) - for "12345678", this returns:

Qxrgm9Le6ljQ/seKzR+rbg==

Which is 24 characters.... ???
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Drebin <th*******@hotmail.com> wrote:
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21 characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or less?? Maybe I'm overthinking the problem somehow?


Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?

DES will encrypt 5 bytes (or more easily, 8 bytes) into 8 bytes, and
then you could use base-64 to go from that to a 12 character form.

Here's some sample code to do just that. Note that it will encrypt
"000123" in the same way as "00123" (and decrypt them both as "123").
If that's a problem, you'll need to think of a slightly different way
of going from the ID to a long, but I'm sure it'll be doable.
using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
static void Main()
{
// In real code you'd need to set an IV and Key to be the same
// thing each time, of course
DESCryptoServiceProvider csp = new DESCryptoServiceProvider();
string encrypted = Encrypt (csp, "123456789");

Console.WriteLine ("Encrypted version: {0}", encrypted);

string plain = Decrypt (csp, encrypted);
Console.WriteLine ("Plain text: {0}", plain);
}

static string Encrypt(DESCryptoServiceProvider csp, string plain)
{
long number = long.Parse(plain);
byte[] bytes = BitConverter.GetBytes(number);
ICryptoTransform trans = csp.CreateEncryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.Close();
}

return Convert.ToBase64String (ms.ToArray());
}
}

static string Decrypt (DESCryptoServiceProvider csp,
string encrypted)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);

ICryptoTransform trans = csp.CreateDecryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(encryptedBytes, 0, encryptedBytes.Length);
cs.Close();
}

byte[] decryptedBytes = ms.ToArray();
if (decryptedBytes.Length != 8)
{
throw new ArgumentException ("encrypted",
"Invalid data");
}
return BitConverter.ToInt64(decryptedBytes, 0).ToString();
}
}
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #9

P: n/a
Tim, thanks for your help.. I read and re-read, but I don't think I get what
you mean here. Do you have an example or code snippet? And when you say
"encrypt" - using which algorithm??

"Tim Gallivan" <no**********************@edu.gov.on.ca> wrote in message
news:u%****************@TK2MSFTNGP14.phx.gbl...
I've done this before: randomly generate a one-time pad each type you need
to encrypt, use it to encrypt your characters, break up the pad into single characters and stick it inside the encrypted string along with dummy
characters. Your decryption code will know the pad and what to decrypt. You can vary this by changing the order of the pad and/or the data, by using
other dummy values. It all depends on how secure you need to be.

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21 characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to

create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars

or
less?? Maybe I'm overthinking the problem somehow?


Nov 16 '05 #10

P: n/a
Drebin <th*******@hotmail.com> wrote:
Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?
This is in a database, and then the 20 chars we're send are in an XML doc -
so assume everything is CHARACTERS.


Right, good.
These are standard U.S. social security numbers, so yes - nine digits that
are 0 through 9. What do you mean representable as 5 bytes??


Well, with 9 digits, there are only 10^9 possibilities - basically
every number from
000000000
to
999999999

(plus distinctions between 012 and 12, for instance, but let's leave
that for the moment).

In fact, I made a mistake before - 9 digits can be represented as a 32-
bit integer easily (look at how big Int32.MaxValue is). I'm suggesting
that instead of thinking of the SSN as a string of digits, you think of
it as an integer. You're basically trying to encrypt a 32-bit integer,
which is much easier than thinking of it as a 9 character string :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #11

P: n/a
Hi, Drebin.
I dont know if SSN is numeric or alphanumeric code. If it's numeric
think a code like:

1) make an array or list that contains chars from "0" to "9" in a random
but *fixed* order:

2,3,1,0,4,5,9,8,6,7

2) loop on YourNumericCode; for each char in SSN get position index in
array (see prev point)

3) you need 5 bit to descrive decimal value "9". Now, convert char index
in binary format and add result to a string/stringbuilder

4) For each iteration you've
0001
00011000
000110000100
....

iterate on this string, get 4 char, convert this substring in a hex code

9 (ssn length) * 4 bit = 36 bits
36 bits/8 => 6 hex chars

finally use some simple algo to make a check digit and put it as last
char of resulting string.

If you want, you can add other "garbage" data to result...

you can add a "seed" code based on value from 1 to 255 (ff).
For each encode operation you can increment this value, and when it's
euqal to 255, reset it to zero...
you can change real code position using random defined char as tag
start/end code..
Is ssn is *alphabetic*, you can use this login simply using 5 bits
insthead 4 (26 d, 1a hex, 11010 binary)
(26= a,b,c,d,..w,x,y,z)

Finally, if ssn is *alphanumeric*, you can use this login simply using 6
bits

26 letters (abcdefg...)
10 numeric symbols (0,1,2,3
max value = 36 (24hex, 100100 binary)
HTH

Alberto Salvati

Nov 16 '05 #12

P: n/a
I chuckled.. that was pretty smart!!! :-)

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Drebin <th*******@hotmail.com> wrote:
Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?


This is in a database, and then the 20 chars we're send are in an XML doc - so assume everything is CHARACTERS.


Right, good.
These are standard U.S. social security numbers, so yes - nine digits that are 0 through 9. What do you mean representable as 5 bytes??


Well, with 9 digits, there are only 10^9 possibilities - basically
every number from
000000000
to
999999999

(plus distinctions between 012 and 12, for instance, but let's leave
that for the moment).

In fact, I made a mistake before - 9 digits can be represented as a 32-
bit integer easily (look at how big Int32.MaxValue is). I'm suggesting
that instead of thinking of the SSN as a string of digits, you think of
it as an integer. You're basically trying to encrypt a 32-bit integer,
which is much easier than thinking of it as a 9 character string :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #13

P: n/a
Disregard, I'm an idiot.. I needed to translated this into VB.NET (because
the guy who's going to support this hates C#).. I accidentally converted
this "number" to a long instead of int.. this works now.. so 1234567890
encrypts to:

DNdt2q3Jhsw=

which is 12 characters - and that's perfect!! Thanks much!! :-)
"Drebin" <th*******@hotmail.com> wrote in message
news:De*****************@newssvr19.news.prodigy.co m...
Jon,

Thanks for your help, but this is what I ran into before (regarding your
code below) - for "12345678", this returns:

Qxrgm9Le6ljQ/seKzR+rbg==

Which is 24 characters.... ???
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Drebin <th*******@hotmail.com> wrote:
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than
21
characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 -
so those are out

So then, I was just going to do an XOR "encryption" (and I use that word lightly) - but you'd have to use a second unique value, for each SSN -
to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20
chars or less?? Maybe I'm overthinking the problem somehow?


Firstly, you need to get the terminology precise - do you mean 20
characters, or 20 bytes? Are the 9 digits just that - digits, 0-9 (and
therefore representable as 5 bytes)?

DES will encrypt 5 bytes (or more easily, 8 bytes) into 8 bytes, and
then you could use base-64 to go from that to a 12 character form.

Here's some sample code to do just that. Note that it will encrypt
"000123" in the same way as "00123" (and decrypt them both as "123").
If that's a problem, you'll need to think of a slightly different way
of going from the ID to a long, but I'm sure it'll be doable.
using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
static void Main()
{
// In real code you'd need to set an IV and Key to be the same
// thing each time, of course
DESCryptoServiceProvider csp = new DESCryptoServiceProvider();
string encrypted = Encrypt (csp, "123456789");

Console.WriteLine ("Encrypted version: {0}", encrypted);

string plain = Decrypt (csp, encrypted);
Console.WriteLine ("Plain text: {0}", plain);
}

static string Encrypt(DESCryptoServiceProvider csp, string plain)
{
long number = long.Parse(plain);
byte[] bytes = BitConverter.GetBytes(number);
ICryptoTransform trans = csp.CreateEncryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.Close();
}

return Convert.ToBase64String (ms.ToArray());
}
}

static string Decrypt (DESCryptoServiceProvider csp,
string encrypted)
{
byte[] encryptedBytes = Convert.FromBase64String(encrypted);

ICryptoTransform trans = csp.CreateDecryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, trans, CryptoStreamMode.Write))
{
cs.Write(encryptedBytes, 0, encryptedBytes.Length);
cs.Close();
}

byte[] decryptedBytes = ms.ToArray();
if (decryptedBytes.Length != 8)
{
throw new ArgumentException ("encrypted",
"Invalid data");
}
return BitConverter.ToInt64(decryptedBytes, 0).ToString();
}
}
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Nov 16 '05 #14

P: n/a
Drebin <th*******@hotmail.com> wrote:
Thanks for your help, but this is what I ran into before (regarding your
code below) - for "12345678", this returns:

Qxrgm9Le6ljQ/seKzR+rbg==

Which is 24 characters.... ???


Oops - didn't check :)

I'm slightly surprised by that, as I thought 8 bytes would still be
encrypted as 8 bytes, which would then become 12 characters.

However, due to my previous mistake about numbers, it's probably
easiest just to convert it to int.Parse, BitConverter.ToInt32, and
check that the decrypted value is 4 bytes long, etc.

That works, giving "TP3IWR2LXJs=" for 123456789.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #15

P: n/a
All set now, that was my mistake.. thanks again for you help!! :-)
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Drebin <th*******@hotmail.com> wrote:
Thanks for your help, but this is what I ran into before (regarding your
code below) - for "12345678", this returns:

Qxrgm9Le6ljQ/seKzR+rbg==

Which is 24 characters.... ???


Oops - didn't check :)

I'm slightly surprised by that, as I thought 8 bytes would still be
encrypted as 8 bytes, which would then become 12 characters.

However, due to my previous mistake about numbers, it's probably
easiest just to convert it to int.Parse, BitConverter.ToInt32, and
check that the decrypted value is 4 bytes long, etc.

That works, giving "TP3IWR2LXJs=" for 123456789.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #16

P: n/a
Drebin <th*******@hotmail.com> wrote:
All set now, that was my mistake.. thanks again for you help!! :-)


Nope, it wasn't your mistake at all - it was a problem in my code as
presented to you. I think you accurately converted the code :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #17

P: n/a
you are overthinking this.

Take a GUID and remove the dashes. That's your new "key". store it as a
string in the code.
XOR the SSN with the key characters in order.

That way, it will not be terribly easy to pick out the pattern.

Normally, you'd want to create a Hash. You may also want to consider using
the Crypto API or CAPICOM to create an MD5 hash, and then take the first 20
characters and XOR them to the second 20 characters to get your value.

That's a pretty hair-brained idea, and I'm NOT certain that the result will
always be unique...

Anyway, good luck,
--- Nick

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or less?? Maybe I'm overthinking the problem somehow?

Nov 16 '05 #18

P: n/a
Sorry,
Try googling "one-time pad" and you'll see the algorithm for encrypting data
using one. They are supposedly unbreakable - as long as you never re-use the
pad.

Say you have this 8 char string to encrypt:

FrTonMqA

and the first 8 chars of your pad are:

12345678

and when you encrypt your string, you have:

$rT*vbBQ

then you can stick your pad inside your encrypted string (or cyphertext).
The rule will be insert pad(1) and (2) after char(2), pad(4) and (3) after
char(3), pad(8) after char(4), pad(7) and (6) after (5), and pad(5) after
char(7), so you get:

$r12T43*8v76bB5Q

On the receiving end, you know the rule, so you strip out and reassemble the
pad, then apply it in a reverse algorithm and you get the original text.

"Drebin" <th*******@hotmail.com> wrote in message
news:ui*****************@newssvr19.news.prodigy.co m...
Tim, thanks for your help.. I read and re-read, but I don't think I get what you mean here. Do you have an example or code snippet? And when you say
"encrypt" - using which algorithm??

"Tim Gallivan" <no**********************@edu.gov.on.ca> wrote in message
news:u%****************@TK2MSFTNGP14.phx.gbl...
I've done this before: randomly generate a one-time pad each type you need
to encrypt, use it to encrypt your characters, break up the pad into single
characters and stick it inside the encrypted string along with dummy
characters. Your decryption code will know the pad and what to decrypt.

You
can vary this by changing the order of the pad and/or the data, by using
other dummy values. It all depends on how secure you need to be.

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21 characters. It doesn't need to be super-secure, just something that isn't plain-text and it HAS to be as unique as the original number. It also does not need to be a symmetric algorithm - we are using this as a way to

create
a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 -
so those are out

So then, I was just going to do an XOR "encryption" (and I use that word lightly) - but you'd have to use a second unique value, for each SSN - to not have this become basically a character swap. In other words, if I use one "key", then "9" always translates to A - for ALL SSN's.. which is bad, because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20

chars or
less?? Maybe I'm overthinking the problem somehow?



Nov 16 '05 #19

P: n/a
The problem with this solution is that you are including the pad in the
message. This is security through obscurity. It only has a chance of working
until an attacker discovers your method, at which point it's completely
useless. i unfortunately don't know enough about attacking cryptographic
systems to know if one could easily break it without knowledge of the
algorithm.

The difficulty with one-time pads is getting the pad to the receiving party
without it being intercepted.

Colin

"Tim Gallivan" <no**********************@edu.gov.on.ca> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Sorry,
Try googling "one-time pad" and you'll see the algorithm for encrypting data using one. They are supposedly unbreakable - as long as you never re-use the pad.

Say you have this 8 char string to encrypt:

FrTonMqA

and the first 8 chars of your pad are:

12345678

and when you encrypt your string, you have:

$rT*vbBQ

then you can stick your pad inside your encrypted string (or cyphertext).
The rule will be insert pad(1) and (2) after char(2), pad(4) and (3) after
char(3), pad(8) after char(4), pad(7) and (6) after (5), and pad(5) after
char(7), so you get:

$r12T43*8v76bB5Q

On the receiving end, you know the rule, so you strip out and reassemble the pad, then apply it in a reverse algorithm and you get the original text.

"Drebin" <th*******@hotmail.com> wrote in message
news:ui*****************@newssvr19.news.prodigy.co m...
Tim, thanks for your help.. I read and re-read, but I don't think I get what
you mean here. Do you have an example or code snippet? And when you say
"encrypt" - using which algorithm??

"Tim Gallivan" <no**********************@edu.gov.on.ca> wrote in message
news:u%****************@TK2MSFTNGP14.phx.gbl...
I've done this before: randomly generate a one-time pad each type you need to encrypt, use it to encrypt your characters, break up the pad into

single
characters and stick it inside the encrypted string along with dummy
characters. Your decryption code will know the pad and what to decrypt.
You
can vary this by changing the order of the pad and/or the data, by
using other dummy values. It all depends on how secure you need to be.

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
> It's a long story really, but the bottom line is we need to encrypt or > obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than
21
> characters. It doesn't need to be super-secure, just something that

isn't
> plain-text and it HAS to be as unique as the original number. It also does
> not need to be a symmetric algorithm - we are using this as a way to
create
> a unique "userid" on a system to which we single-signon. So it's
used > programmatically only.
>
> DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is

40 - so > those are out
>
> So then, I was just going to do an XOR "encryption" (and I use that word > lightly) - but you'd have to use a second unique value, for each
SSN - to
> not have this become basically a character swap. In other words, if
I use
> one "key", then "9" always translates to A - for ALL SSN's.. which
is bad,
> because it's very easy to pick out the pattern.
>
> SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20

chars or
> less?? Maybe I'm overthinking the problem somehow?
>
>



Nov 16 '05 #20

P: n/a
Here's a cool trick you could try. Since your clear in simple ascii
characters, run it through Base64 *decode* first. This will give it a
byte[] that's 25% smaller than the original. (Actually, since it would have
to pad the input string out to a multiple of 4 character before reducing it
to a multiple of 3, you'll end up of 9 bytes).

Play with those 9 bytes as you please (swap some of them, xor them with
some constant, etc). Then Base64 encode them, and you're back up to only 12
characters. Since each byte of the compress array is made up of parts of
two character, it should have the xor/character swap problem you describe.

Actually, with only 10 characters domain in your input string, Jon's
idea of converting it to an integer would probably be best, but this works
for anything whose domain is just upper/lower case letters & digits.

--
Truth,
James Curran
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
(note new day job!)

"Drebin" <th*******@hotmail.com> wrote in message
news:7k*******************@newssvr31.news.prodigy. com...
It's a long story really, but the bottom line is we need to encrypt or
obfuscate a clear-text 9-digit SSN/taxpayer ID into something less than 21
characters. It doesn't need to be super-secure, just something that isn't
plain-text and it HAS to be as unique as the original number. It also does
not need to be a symmetric algorithm - we are using this as a way to create a unique "userid" on a system to which we single-signon. So it's used
programmatically only.

DES/3DES/RC2 are 24 characters, MD5 is 24 (I think?) and SHA1 is 40 - so
those are out

So then, I was just going to do an XOR "encryption" (and I use that word
lightly) - but you'd have to use a second unique value, for each SSN - to
not have this become basically a character swap. In other words, if I use
one "key", then "9" always translates to A - for ALL SSN's.. which is bad,
because it's very easy to pick out the pattern.

SO.. anyone have any ideas of how to mangle up a 9-digit SSN in 20 chars or less?? Maybe I'm overthinking the problem somehow?

Nov 16 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.