PHP code broke when moving from PHP4 to PHP5

liunx

Guest
I am using the code below to encrypt/decrypt URLs that I am sending my users, but I upgraded to PHP5 on my Red Hat Linux server and I can not get the decrypt to work properly becuase I can only get part of the ecrypted text decrypted about 20% of the time. I have never gotten a full decrypt of a 100 char string. Can some please help when there is time becuase I am stuck on this one? It seams that I can encrypt the URL fine, and that is what is confusing me because the code looks the same format type on the decrypt. Right now I tared my code up to run on a different web server until I get this to work. Thank you in advanced for the time and help.

FROM: <!-- m --><a class="postlink" href="http://us3.php.net/md5">http://us3.php.net/md5</a><!-- m -->
Alexander Valyalkin 30-Jun-2004 02:41
Below is MD5-based block cypher (MDC-like), which works in 128bit CFB mode. It is very useful to encrypt secret data before transfer it over the network.


$iv_len - initialization vector's length.
0 <= $iv_len <= 512

<?php

function get_rnd_iv($iv_len)
{
$iv = '';
while ($iv_len-- > 0) {
$iv .= chr(mt_rand() & 0xff);
}
return $iv;
}

function md5_encrypt($plain_text, $password, $iv_len = 16)
{
$plain_text .= "\x13";
$n = strlen($plain_text);
if ($n % 16) $plain_text .= str_repeat("\0", 16 - ($n % 16));
$i = 0;
$enc_text = get_rnd_iv($iv_len);
$iv = substr($password ^ $enc_text, 0, 512);
while ($i < $n) {
$block = substr($plain_text, $i, 16) ^ pack('H*', md5($iv));
$enc_text .= $block;
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return base64_encode($enc_text);
}

function md5_decrypt($enc_text, $password, $iv_len = 16)
{
$enc_text = base64_decode($enc_text);
$n = strlen($enc_text);
$i = $iv_len;
$plain_text = '';
$iv = substr($password ^ substr($enc_text, 0, $iv_len), 0, 512);
while ($i < $n) {
$block = substr($enc_text, $i, 16);
$plain_text .= $block ^ pack('H*', md5($iv));
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return preg_replace('/\\x13\\x00*$/', '', $plain_text);
}

/******************************************/
$plain_text = 'very secret string';
$password = 'very secret password';
echo "plain text is: [${plain_text}]<br />\n";
echo "password is: [${password}]<br />\n";

$enc_text = md5_encrypt($plain_text, $password);
echo "encrypted text is: [${enc_text}]<br />\n";

$plain_text2 = md5_decrypt($enc_text, $password);
echo "decrypted text is: [${plain_text2}]<br />\n";

?>I just ran the code you posted on PHP 5.1.2 on OS X 10.4.4, and it worked as expected (I ran it from the interactive console in PHP 5).

What version of PHP 5 are you running?Thank you for the quick reply. I am running php 5.1.2 on Linix. I am thinking that I did not put something in my config, but I do not know what I could be missing if since the encryption works. As soon as I switch Apache to use the php4 module it works again. any ideas.Here is my config for php 5.1.2

'./configure' '--build=i386-redhat-linux' '--host=i386-redhat-linux' '--target=i386-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib' '--libexecdir=/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/usr/com' '--mandir=/usr/share/man' '--infodir=/usr/share/info--with-config-file-path=/etc' '--with-config-file-scan-dir=/etc/php.d--enable-force-cgi-redirect' '--enable-debug' '--enable-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-db4=/usr' '--with-curl' '--with-exec-dir=/usr/bin' '--with-freetype-dir=/usr' '--with-png-dir=/usr' '--with-gd' '--enable-gd-native-ttf' '--without-gdbm' '--with-gettext' '--with-ncurses' '--with-gmp' '--with-iconv' '--with-jpeg-dir=/usr' '--with-openssl' '--with-png' '--with-pspell' '--with-expat-dir=/usr' '--with-xmlrpc' '--with-zlib' '--with-layout=GNU' '--enable-bcmath' '--enable-exif' '--enable-ftp' '--enable-magic-quotes' '--enable-safe-mode' '--enable-sockets' '--enable-sysvsem' '--enable-sysvshm' '--enable-track-vars' '--enable-trans-sid' '--enable-yp' '--enable-wddx' '--with-pear=/usr/share/pear' '--with-imap' '--with-imap-ssl' '--with-kerberos' '--with-ldap' '--with-mysql=/usr' '--with-pgsql' '--with-unixODBC=/usr' '--enable-memory-limit' '--enable-shmop' '--enable-calendar' '--enable-dbx' '--enable-dio' '--enable-mbstring' '--enable-mbstr-enc-trans' '--enable-mbregex' '--with-mime-magic=/usr/share/file/magic.mime' '--with-apxs2=/usr/sbin/apxs' '--enable-sigchild' '--with-oci8=/u01/app/oracle/product/10.2.0/client_1' '--enable-libxml' '--with-xml' '--with-oracle=/u01/app/oracle/product/10.2.0/client_1' '--with-dom=/usr' '--with-dom-xslt=/usr' '--with-pcre-regex=/usr' '--with-snmp=/usr' '--enable-ucd-snmp-hack'

Loaded Modules

core prefork http_core mod_so mod_access mod_auth mod_auth_anon mod_auth_dbm mod_auth_digest util_ldap mod_auth_ldap mod_include mod_log_config mod_env mod_mime_magic mod_cern_meta mod_expires mod_deflate mod_headers mod_usertrack mod_setenvif mod_mime mod_dav mod_status mod_autoindex mod_asis mod_info mod_dav_fs mod_vhost_alias mod_negotiation mod_dir mod_imap mod_actions mod_speling mod_userdir mod_alias mod_rewrite mod_proxy proxy_ftp proxy_http proxy_connect mod_cache mod_suexec mod_disk_cache mod_file_cache mod_mem_cache mod_cgi mod_php5 mod_auth_kerb mod_auth_mysql mod_auth_pgsql mod_authz_ldap mod_perl mod_python mod_ssl mod_dav_svn mod_authz_svn mod_jkOk I think I found the problem, but I do not know how to fix it. I think it is the '+', pluses in the encrypted URL that may be getting removed. I typed up some code to help easy the trouble shooting process. Is this a "feature" in php5?



File: 3.php
<?php

function get_rnd_iv($iv_len)
{
$iv = '';
while ($iv_len-- > 0) {
$iv .= chr(mt_rand() & 0xff);
}
return $iv;
}

function md5_encrypt($plain_text, $password, $iv_len = 16)
{
$plain_text .= "\x13";
$n = strlen($plain_text);
if ($n % 16) $plain_text .= str_repeat("\0", 16 - ($n % 16));
$i = 0;
$enc_text = get_rnd_iv($iv_len);
$iv = substr($password ^ $enc_text, 0, 512);
while ($i < $n) {
$block = substr($plain_text, $i, 16) ^ pack('H*', md5($iv));
$enc_text .= $block;
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return base64_encode($enc_text);
}
function md5_decrypt($enc_text, $password, $iv_len = 16)
{
$enc_text = base64_decode($enc_text);
$n = strlen($enc_text);
$i = $iv_len;
$plain_text = '';
$iv = substr($password ^ substr($enc_text, 0, $iv_len), 0, 512);
while ($i < $n) {
$block = substr($enc_text, $i, 16);
$plain_text .= $block ^ pack('H*', md5($iv));
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return preg_replace('/\\x13\\x00*$/', '', $plain_text);
}

$LASTDATEBINDPW = "password";
$encrypt_info = $_GET['encrypt'];
$encrypt = md5_encrypt("rzapat1||MyPassWD1928%@||MyName||LastNames||[email protected]||123-123-123",$LASTDATEBINDPW);
$decrypt = md5_decrypt($encrypt, $LASTDATEBINDPW);
echo "<b>static decrypt: </b> $decrypt<BR /><BR /><b>encrypted url (click to decrypt):</b><BR /><a href='http://www.phpbuilder.com/board/archive/index.php/3.php?encrypt=$encrypt'>$encrypt</a><BR /><BR /><BR /><BR />";

$decrypturl = md5_decrypt($encrypt_info, $LASTDATEBINDPW);
echo "<b>decrypt from url:</b> $decrypturl<BR /><BR /><b>Encryption String from the URL: </b><BR /> $encrypt_info";

?>A + sign in an URL means a space. To my knowledge, it has always been like this. If you want to keep a literal plus, then maybe try using rawurlencode to encode the encrypted string so you can pass it in a url, and using rawurldecode to decode it prior to decryption.That worked!!! It must be something php started to enforce in php5. Thank you very much for you help.
 
Back
Top