obfuscate or encrypt some plain text data in PHP

19,136

Solution 1

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

Solution 2

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

Solution 3

Try these PHP functions convert_uuencode and convert_uudecode:

function encrypt_decrypt ($data, $encrypt) {
    if ($encrypt == true) {
        $output = base64_encode (convert_uuencode ($data));
    } else {
        $output = convert_uudecode (base64_decode ($data));
    }
    return $output;
}

$enc_txt = encrypt_decrypt ("HELLO DATA", true);
echo $enc_txt."\n"; // KjIkNSwzJFxAMSQlNDAwYGAKYAo=
echo encrypt_decrypt ($enc_txt, false); // HELLO DATA

Solution 4

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

Solution 5

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,

Share:
19,136
KM.
Author by

KM.

Updated on June 05, 2022

Comments

  • KM.
    KM. about 2 years

    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.

  • VolkerK
    VolkerK about 15 years
    oO You employ developers that are unable to spot and decode base64? (just kidding, couldn't resist...)
  • dusoft
    dusoft about 15 years
    anyone can tell on the first sight base64 is used and decode it in a second. how does that make SMS "undreadable"?
  • karim79
    karim79 about 15 years
    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.
  • Colin Pickard
    Colin Pickard about 15 years
    There are some locks that exist just to keep honest people honest.
  • KM.
    KM. about 15 years
    I really like the same length string output, however, I'm not on mysql. The rot13 looks promising
  • Sikshya Maharjan
    Sikshya Maharjan about 15 years
    But...I think rot13 was a joke.
  • Sikshya Maharjan
    Sikshya Maharjan about 15 years
    @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.
  • KM.
    KM. about 15 years
    @ricebowl, but I only need a simple solution
  • KM.
    KM. almost 15 years
    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.
  • Admin
    Admin over 11 years
    How did you choose or generate the strings you are using above. rot13 looks simpler, why the added complexity?
  • KM.
    KM. over 11 years
    @pure_code, from the manual: The ROT13 encoding simply shifts every letter by 13 places in the alphabet while leaving non-alpha characters untouched. Encoding and decoding are done by the same function, passing an encoded string as argument will return the original version. this wasn't too much harder, but it makes it much harder to get any info out of the encoded string.
  • Admin
    Admin over 11 years
    Yes, I know. What I was asking is how did you generate the two strings. I'm too lazy to count but it looks like you took ASCI (256 characters) and shifted 128 characters
  • Admin
    Admin over 11 years
    rot13 is perfect if you need something to be un-readable but not un-hackable.
  • KM.
    KM. over 11 years
    probabily something like that, if you have a numbers table it is simple using CHAR, something on the lines of select char(number) from numbers where number<255
  • JustAMartin
    JustAMartin over 8 years
    @David Thomas Actually you can "keep honest people honest". Imagine - you have to work with a database which contains private SMS messages and you, being an honest man, don't want to read this private stuff. If messages are stored as plain text, you won't be able "not to read them" because you can't turn "reading mode off" in your brain. Reading private stuff might make you feel less honest, therefore base64 is good enough to prevent this. It does not protect against dishonesty, but it helps to prevent discomfort for honest developers who don't want to see private information.
  • Vishal Kumar Sahu
    Vishal Kumar Sahu about 7 years
    Why did you ignore the word 'length'?
  • atiruz
    atiruz about 7 years
    Functions do not require it