5

Based on some examples on stackoverflow I've created a page which crpyts and decrypts the text that comes from html form. But somehow this is sometimes working sometimes not and usually it is not.

Why is this happening? Does htmlencode modifies the keys on posting proccess ? How do I fix that? Should I use base64 ?

<?php
$key_size = mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
$encryption_key = openssl_random_pseudo_bytes($key_size, $strong);

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM); // 16 bytes output


if($_POST){
    $iv = $_POST["iv"];
    $encryption_key = $_POST["key"];
    $string = $_POST["msg"];


    if($_POST["do"]=="encrypt"){
        echo "crypted";
        $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_CFB, $iv);
    }else{
        echo "de-crypted";
        $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_CFB, $iv);
    }

}

?>
<div class="main" id="main">
    <form method="POST" action="">
    <input type="text" value="<?php echo $iv; ?>" name="iv"/> <br/>
    <input type="text" value="<?php echo $encryption_key; ?>" name="key"/><br/>

    <textarea name="msg"><?php echo $result; ?></textarea><br/>
    <select name="do"><option>encrypt</option><option>decrypt</option></select><br/>
    <input type="submit" value="GO"/>
    </form>

</div>

live example can be found @ http://lab.ohshiftlabs.com/crypt/

Community
  • 1
  • 1
siniradam
  • 2,727
  • 26
  • 37
  • R u sure u have installed mcrypt module – user3004356 Feb 20 '14 at 11:49
  • Otherwise I think it suppose to return error, but yes, according to phpinfo it is installed; mcrypt support enabled mcrypt_filter support enabled Version 2.5.8 Api No 20021217 Supported ciphers cast-128 gost rijndael-128 twofish arcfour cast-256 loki97 rijndael-192 saferplus wake blowfish-compat des rijndael-256 serpent xtea blowfish enigma rc2 tripledes Supported modes cbc cfb ctr ecb ncfb nofb ofb stream – siniradam Feb 20 '14 at 11:52
  • Which OS are you using...try to run this ``. This will reveal the details – user3004356 Feb 20 '14 at 11:54
  • I tried in my local. Seems to be working fine. Double check your php info. – Rikesh Feb 20 '14 at 12:00

1 Answers1

1

Here is some commented code that you may find useful. I think the main issue with your code is that the output from the 'mcrypt' routines are in 'binary' format and will need to be encoded in some sort of HTML 'safe' format. I have used base64.

The code has been tested.

<?php
/*
 * PHP 5.3.18 on windows XP
 *
 * I don't have open_ssl active from PHP so used MCRYPT_RAND for the salt.
 * It is adequate for this exercise.
 *
 * As the encoded SALT and encrypted output are binary code i have converted all
 * the output to Base64 encoding to ensure it is HTML safe.
 *
 * It selects the appropriate default action in the 'do' select list.
 *
 * There is a new 'salt' generated at each encryption and the user is prevented from
 * changing it by making the display field as 'readonly'. Normally this would be a 'hidden' field'.
 *
 */

$isEncrypted = null; // used to set default output options
                     // i like to pre-declare the script 'global' variables


$key_size = mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);


if($_POST){ // we have some input...

    $encryption_key = $_POST["key"];
    $string = $_POST["msg"]; // this may be base64 encoded...


    if($_POST["do"]=="encrypt"){
        $isEncrypted = true; // used to set defaults

        $iv = mcrypt_create_iv($iv_size,  MCRYPT_RAND); // new salt with each encryption
        $result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_CFB, $iv);
        $result = base64_encode($result); // $result is binary so encode as HTML safe.


    }else{
        $isEncrypted = false; // used to set defaults

        $iv = base64_decode($_POST["iv"]); // get current salt converted back to binary format
        $string = base64_decode($string); // convert encoded text back to binary string
        $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_CFB, $iv);
    }
}else{ // no input so create something useful...
  $isEncrypted = false; // used to set default actions

  $result = 'enter text to encrypt...'; // sample text
  $iv = mcrypt_create_iv($iv_size,  MCRYPT_RAND); // new salt
  $encryption_key = substr('testing!' . uniqid() . '!testing', 0, $key_size);
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Test Encryption with base64 encoding.</title>
  </head>

  <body>
    <div class="main" id="main">

        <!-- heading -->
        <strong><?php echo $isEncrypted ? 'Encrypted' : 'Decrypted'; ?></strong><br/>

        <form method="POST" action="">

            <!-- do not allow the user to change the salt by setting 'readonly' -->
            <input type="text" value="<?php echo base64_encode($iv); ?>" readonly name="iv"/> <br/>

            <!-- supply a suggested password but the user can change it -->
            <input type="text" value="<?php echo $encryption_key; ?>" name="key"/><br/>

            <!-- either show the encoded text as HTML safe string -->
            <!--- or show as plain text -->
            <textarea name="msg" ><?php echo $result; ?></textarea><br/>

            <!-- set the appropriate action as the default -->
            <select name="do">
              <option <?php echo $isEncrypted ? 'selected' : ''; ?>>decrypt</option>
              <option <?php echo $isEncrypted ? '' : 'selected'; ?>>encrypt</option>
            </select><br/>

            <input type="submit" value="GO"/>
        </form>
    </div>
  </body>
</html>
Ryan Vincent
  • 4,483
  • 7
  • 22
  • 31
  • Just as I thought, I was just thinking should use base64 or a decoder function to make it htmlsafe. This is perfect example thank you. Since I'm here in Turkey, I'll use this for crypted messaging to avoid from my government. – siniradam Feb 21 '14 at 09:14