There are two keys: the main is aes128 and the second is XTEA, used just for randomization of data inside the AES. Randomization is done with secret random key that is not know even if someone knows exactly what is encrypted. Also the key is produced by doing hash many number of times and this hash is salted with the iv so it is not possible to make a dictionary attack with precomputed hashes.

function aes128ctr_en($data,$key,$hash_rounds = 0) {
    //iv is created
    $iv = mcrypt_create_iv(16,MCRYPT_DEV_URANDOM);
    //internal secret random string is created so no one knows what
    //is exactly encoded by main cipher
    $xtea = mcrypt_create_iv(16,MCRYPT_DEV_URANDOM);
    //password is hashed in many rounds to prevent dictionary attack,
    //hashing is done with individual iv for hmac so it make no sense to use
    //precalculated hashes
    for($i=0;$i<=$hash_rounds;++$i) $key = hash_hmac('sha256',$key,$iv,true);
    //string is randomized for use in aes, so no one knows what actually will be encoded
    //this is not actual encoding so password is stored inside with xtea encoded string,
    //second half of this password is used as IV for xtea
    $data = $xtea.mcrypt_encrypt('xtea',$xtea,$data,'ofb',substr($xtea,8));
    //hash is added to check if return string is really what we looked for,
    //must match with string on decoding
    $data = hash('md5',$data,true).$data;
    //actual encoding, IV is prepended to encrypted string
    return $iv.mcrypt_encrypt('rijndael-128',$key,$data,'ctr',$iv);

function aes128ctr_de($data,$key,$hash_rounds = 0) {
    $iv = substr($data,0,16);
    $data = substr($data,16);
    for($i=0;$i<=$hash_rounds;++$i) $key = hash_hmac('sha256',$key,$iv,true);
    $data = mcrypt_decrypt('rijndael-128',$key,$data,'ctr',$iv);
    $md5 = substr($data,0,16);
    $data = substr($data,16);
    if (hash('md5',$data,true)!==$md5) return false;
    $xtea = substr($data,0,16);
    $data = substr($data,16);
    return mcrypt_decrypt('xtea',$xtea,$data,'ofb',substr($xtea,8));

$key = 'suPer_secret aAnd L10ng ppswrd$%';
$encrypted = aes128ctr_en('the bomb will blow up at 1 pm',$key,12345);
echo aes128ctr_de($encrypted,$key,12345);

I really don't have knowledge to make it better. I'm not that educated in all this to read RFCs and make algorithms out of it. I'm also constrained to methods that are precompiled in core PHP binary as I want these methods to be able to run on remote servers.

  • 3
    \$\begingroup\$ I hope this is the last of your "I wrote some algorithm and don't know exactly how it works, but tell me if it is secure" questions. At the very least you could have used test data to compare the output of your unreadable functions to a reference implemention like openssl. \$\endgroup\$
    – mario
    Commented Jan 5, 2011 at 21:55
  • 4
    \$\begingroup\$ take sha256, md5, xtea, and aes-128, place into a blender with some cool random bytes, and press the liquefy button. Pour the results out onto Stackoverflow for analysis. \$\endgroup\$
    – GregS
    Commented Jan 5, 2011 at 22:11
  • 1
    \$\begingroup\$ You should read Security through obscurity. \$\endgroup\$
    – wimvds
    Commented Jan 6, 2011 at 14:42
  • 3
    \$\begingroup\$ Well, the comments do very much improve this question. Spend your reputation on a bounty now and it's likely to get answered instead of closevoted. - It's even obvious now why the first function is a blob instead of being split up into the three subparts (hashing, shuffling, encryption stage). - At the very least it looks like a plausible approach. Yet I'm not stating this as answer, but to make it go away faster. Also consider that while the algorithm might be ok; running this in a PHP runtime ensures that the plain $key, $iv and $xtea variables will remain somewhere in memory on script exit. \$\endgroup\$
    – mario
    Commented Jan 6, 2011 at 20:01
  • 1
    \$\begingroup\$ Safe for what? What are you trying to achieve? What is your threat model? Why have you chosen the algorithms and compositions that you have? Why are the existing compositions of algorithms unsuitable for your purposes? \$\endgroup\$
    – crazyscot
    Commented Jan 9, 2011 at 10:50

2 Answers 2


You should use a key strengthening function like PKBDF2, scrypt or bcrypt to generate a key from the password. The part with XTEA is useless: you're relying on security through obscurity. You shouldn't hash before encrypting if you want to ensure the data has not been tampered with. Use HMAC SHA-256 on the encrypted data.

And finally: don't write your own crypto algorithm. Use well known and audited solutions.


The basic answer is: No

Where is your random seed being generated from? (Oh wait, you are not using a random see - seriously big issue #1) Where it is being stored? What cryptographic symmetric ciphers are being used to generate your seed.

You expect the method you are using to be secure? You expect your server to never be compromised?

Failure to apply systematic cryptographic principles to the very basic of what you appear to be trying to do (Security through Obscurity) will always result in a failure of your cryptographic procedures because you fail to understand the necessary principles that need to be applied.

All I see is a whole lot of code designed to do one thing, yet is 100% at risk because you have failed to do other things that are necessary to the process of data encryption.

All that said, it would be very easy to produce something more secure than your 33 lines of code.

But first you need to learn the basics. After that, start looking into using openssl_public_encrypt() and Crypt_Blowfish().

In about 8-10 lines of code you can have a solid cryptographic procedure that will be much more secure than your StO method that you are attempting here - and use methods that are time-proven to be unbreakable by all modern standards within the RAT (Reasonable Amount of Time) factor.

  • \$\begingroup\$ WHAT 33 lines of code ? the encoding part is only 6 lines, what are you talking about ?, Second - didn't you see MCRYPT_DEV_URANDOM ? \$\endgroup\$
    – rsk82
    Commented Jan 27, 2011 at 9:37
  • \$\begingroup\$ Regardless of it being 6 lines or not, the code still fail the very basic of cryptographic methodology. Hard-coded seeds are never - and never will be - secure. \$\endgroup\$
    – Yokhannan
    Commented Jan 28, 2011 at 7:07
  • \$\begingroup\$ Sorry but I do not understand what "hard coded seed" means in this context ? I'm generating one public seed that seves as IV for crypt and one secret that is used to randomize string that is inside. \$\endgroup\$
    – rsk82
    Commented Jan 30, 2011 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.