0

I'm looking for encrypt/decrypt functions that will encode numbers (0, 1, 2, ...) into strings, such that these strings will look random, and later the number could be decodes back from the string.

For example: 3 will be encrypted to ABFQWEMasdEE, and 6 will be encrypted to poad_Asd#@sad.

If I could control the number of characters in the encrypted string, and also which characters can appear there, it could be great !


UPDATE

I end up with this solution:

<?php    

$key = 'secret_password';

for ($i = 100; $i < 110; $i++) {
    $text = "$i";
    $encrypted = encrypt($text, $key);
    $decrypted = decrypt($encrypted, $key);
    $decrypted = rtrim($decrypted, "\0");
    $ok = ($text === $decrypted);
    if (!$ok) {
        exit('********** BUG BUG BUG BUG BUG ***********');
    }
    echo '[' . $text . '] [' . $encrypted . '] [' . $decrypted . '] ' . ($ok ? 'OK' : 'BUG BUG BUG BUG BUG BUG BUG') . '<br />';
}
exit('***** OK ******');

function encrypt($data, $key) {     
    $td = mcrypt_module_open('cast-256', '', 'ecb', '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $encrypted_data = mcrypt_generic($td, $data);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return base64_encode($encrypted_data);
}   

function decrypt($encoded_64, $key) {
    $td = mcrypt_module_open('cast-256', '', 'ecb', '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $decrypted_data = mdecrypt_generic($td, base64_decode($encoded_64));
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $decrypted_data;
}  

?>

which provides the following output:

[100] [9UA0Maq3MGp0CzMOWcpOpg==] [100] OK
[101] [Y5WKH7J1+k0bFqsGw1jmrA==] [101] OK
[102] [NqV2opJc7CNq5O3lcuWKMw==] [102] OK
[103] [1FpJhHe+vrK6aKA54VR53Q==] [103] OK
[104] [MHQoYCqL4yCI9jKg1U0UYw==] [104] OK
[105] [6Qq9aXEn46xpDgv8CvnK7Q==] [105] OK
[106] [UGk1/byT7wpoFM59Uy/pdg==] [106] OK
[107] [39kyPA49zAZsCFx3pt6bYw==] [107] OK
[108] [YccDSimEf3C0NKDaVOf4kA==] [108] OK
[109] [PfmvLfVR4+gi9y9v/6efZQ==] [109] OK
***** OK ******

The strings looks random (except the == at the end) and all of the same size. Not perfect solution, but good enough !

Thank you all !!

Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746
  • 1
    Turning arbitrary length input into fixed length output is usually a property of a *hash function*, not an encryption function. – deceze Aug 06 '10 at 05:57
  • 1
    Hash functions are normally not bijective. He wants something that is reversible. – Amadan Aug 06 '10 at 06:01
  • 2
    @Amadan Yes, and reversible encryption is not usually fixed length. – deceze Aug 06 '10 at 06:05
  • 1
    Check out this question: http://stackoverflow.com/questions/1391132/two-way-encryption-in-php – Jacob Relkin Aug 06 '10 at 06:07
  • @deceze: I am not sure a scheme couldn't be found. Obviously, fixed-length of cyphertext imposes a limit to the numbers being encoded. For instance, if you transform 0-255 into 000-255, or 00000000-11111111, you get fixed-length plaintext, for which it is not unreasonable to expect a fixed-length cyphertext. The trick is how to make it sufficiently random-looking, and yet reversible. My math-fu is weak. – Amadan Aug 06 '10 at 06:12
  • @Amadan You're right. Looking at his/her recent questions though, I do believe the OP is looking for the wrong kind of solution to his/her problem to begin with. Coming up with a custom scheme may be a waste of time, and I'm not aware of a general purpose encryption that is fixed length. My crypt foo is weak though, too. :) – deceze Aug 06 '10 at 06:17
  • The equal signs '=' are for padding an encrypted string to size. It's easy to tell it's base64 encoded, but encoding != encryption. Decoding from base64 gives you the cyphertext, which is still unreadable - and in case of AES - proven indistinguishable under chosen plain-text attack. (IND-CPA) when used in any mode but ECB. – NullUserException Aug 06 '10 at 06:54

4 Answers4

2

You can use one of PHP's encryption functions (mcrypt) to encrypt your data, then use base64_encode to encode it into a string that can be sent as text.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
0

look at base64_encode and base64_decode.

Rostyslav Dzinko
  • 39,424
  • 5
  • 49
  • 62
bcosca
  • 17,371
  • 5
  • 40
  • 51
0

Have a look at the Crypt_XXTEA Pear Package. You can encrypt/decrypt arbitrary Strings with it. It uses the XXTEA block cipher algorithm (see XXTEA at Wikipedia). If you want to have a "nice" format, you can additionally uuencode the encrpted output.

towe75
  • 1,470
  • 10
  • 9
  • 2
    Why use that when you can use a proven scheme like Rijndael (AES) ? Not saying that XXTEA is bad, it's just not as battle-tested as AES. – NullUserException Aug 06 '10 at 06:20
0

Use something simple like rot13 and append a extra set of characters to each number. Yes this is a really weak form of encryption but it solves the question and you can make the output match what ever you want.

If the user wants something more complex then try using tweber's answer , but then you cant really control the length or randomness of the string output.

RC1140
  • 8,423
  • 14
  • 48
  • 71