views:

913

answers:

6

I need to obfuscate or encrypt some plain text data in my php 5.2 application.

I'd prefer a solution that would have input string and output string retain the same length.

This does not need to extremely strong, as there are numerous other layers of security in place. Strong would be good, but this will just keep programmers/dba/support people/etc from accidentally reading the text from within the database.

key considerations

  • EDIT ADD I'd prefer a solution that would have input string and output string retain the same length.
  • only string text will be obfuscated/encrypted for storage in a database
  • the php application will need to obfuscate/encrypt the data before the database save and will need to un-obfuscate/dencrypt following the database read
  • this is a modification to an existing application
  • only some columns will need to be obfuscated/encrypted
  • only some rows will need to be obfuscated/encrypted, based on a Type field
  • there are only a few load/save points to handle
  • max column size is already determined for some fields, but not for others, but I'd prefer a solution to work within the existing size of the restricted fields
  • EDIT, ADD the key will be probably be a composite of some Primary key info +uneditable fields

here is a sample database table and data:

int           char(1) varchar(24)              int      date
MyPrimaryKey  RowType UserText                 UserNo   DateChange
------------  ------- ------------------------ -------- ----------------
1             N       nothing special here     43       6/20/2009 12:11am
2             N       same thing, wow!         78       6/23/2009 1:03pm
3             S       fBJKg}.jkjWfF78dlg@45kjg 43       6/25/2009 6:45am
4             N       same old, same old text  21       6/25/2009 8:11am

The application would load and display rows 1,2, and 4 normally. However it would conditionally (based on row type) handle the text in row 3 using this obfuscate/encrypt and un-obfuscate/decrypt logic.

Can anyone provide obfuscate/encrypt and un-obfuscate/decrypt functions code, links, and or pointer that would help here?

thanks!

EDIT
I like the simple base64 encoding idea, but is there a method that can keep the data within a fixed size. All methods listed so far have the output value larger than the input value. This will be a problem for some columns, where the user can enter in 50 characters and it is stored in a varchar(50) column.

+5  A: 

How about base64 encoding? We use to use that to make SMS messages in our SMS Gateway DB unreadable by the developers.

karim79
oO You employ developers that are unable to spot and decode base64? (just kidding, couldn't resist...)
VolkerK
anyone can tell on the first sight base64 is used and decode it in a second. how does that make SMS "undreadable"?
dusoft
Our concern was not to 'encrypt' just to make it 'not readily readable'. I was one of the developers and yes, I could have decoded any of it in a second.
karim79
There are some locks that exist just to keep honest people honest.
Colin Pickard
@dusoft: his SMS is meant to be 'undreadable'? =)
David Thomas
@Colin: you don't *have* to keep honest people honest; that's *why* they're honest! ...ugh. The vitriol's not entirely aimed at you, it's just I got sick of hearing this -stupid- argument from the RIAA and MPAA.
David Thomas
+4  A: 

There are a few options.

If you want very strong, you could look into mcrypt.

But if it's only so working developers cant read the text without some work to actually do it. Then you could just BASE64 encode it or uuencode it

Ólafur Waage
+1  A: 

Try using the mcrypt library. It's not included with standard PHP, but it's easily downloadable and very commonly used. Here's a quick tutorial on what you can do with it.

It's best to make sure the key you use for the encryption is stored in a secure place, but if you aren't really concerned about security, you'd probably be OK just hardcoding the key into your code somewhere.

Eric Petroelje
+2  A: 

If you have mcrypt installed (all my current PHP environments have), you could use mcrypt_encrypt and mcrypt_decrypt like this:

function encrypt ($text) {
  global $key;
  return mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, "abcdefghijklmnopqrstuvwxyz012345");
}

function decrypt ($secret) {
  global $key;
  return rtrim (mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $key, $secret, MCRYPT_MODE_ECB, "abcdefghijklmnopqrstuvwxyz012345"), "\0");
}

which uses a global $key and AES (very strong).

Drawbacks are performance (in comparison to simpler ones like Base64) and that you somehow have to fix a key.

Cheers,

Boldewyn
+1  A: 

if you're using mysql around version 5, then you don't even need much php for it, you can do it inside your query with the mysql string functions encrypt(text, password) and decrypt(text, password)

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html

  • DECODE(crypt_str,pass_str)

    Decrypts the encrypted string crypt_str using pass_str as the password. crypt_str should be a string returned from ENCODE().

  • ENCODE(str,pass_str)

    Encrypt str using pass_str as the password. To decrypt the result, use DECODE().

    The result is a binary string of the same length as str.

    The strength of the encryption is based on how good the random generator is. It should suffice for short strings.

update: another possibility would be rot13 ^^

Schnalle
I really like the same length string output, however, I'm not on mysql. The rot13 looks promising
KM
But...I think rot13 was a joke.
David Thomas
@ricebowl, but I only need a simple solution
KM
rot13 was indeed a joke. rot13 is ALWAYS a joke ^^
Schnalle
+2  A: 

for simple obfuscation use strtr() - Translate certain characters:
string strtr ( string $str , string $from , string $to )

to encode in php:

$readable='This is a special test string ABC123 ([+,-!#$%&*])';    
$unreadable=strtr($readable,' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
                           ,'¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ '
                      );
print $unreadable; //outputs: "ÕéêôAêôAâAôñæäêâíAõæôõAôõóêïèAÂÃIJ³´A©Ü¬­®¢¤¥¦§«Þª"

to decode in php:

$unreadable='ÕéêôAêôAâAôñæäêâíAõæôõAôõóêïèAÂÃIJ³´A©Ü¬­®¢¤¥¦§«Þª';
$readable=strtr($unreadable,'¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ '
                           ,' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'

               );
print $readable; //outputs: "This is a special test string ABC123 ([+,-!#$%&*])"

you can easily replicate this logic in the DB if necessary (without looping): Using a Table of Numbers, by Erland Sommarskog

KM
I really likes the base 64 idea, but I need the data to fit into existing database fields. The rot13() was fairly simple and kept the same size, but this strtr() is good enough for my purpose.
KM