Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : String Functions : md5

md5

Calculate the md5 hash of a string (PHP 4, PHP 5, PECL hash:1.1-1.3)
string md5 ( string str [, bool raw_output] )

Example 2420. A md5() example

<?php
$str
= 'apple';

if (
md5($str) === '1f3870be274f6c49b3e31a0c6728957f') {
   echo
"Would you like a green or red apple?";
   exit;
}
?>

Related Examples ( Source code ) » md5






Code Examples / Notes » md5

peter

Use it Online
md5-online.com
Helps trying stuff without programming too much


maximius

This is just something I made while looking into MD5 and SHA-1, how they can be exploited, and whatnot.
  /**
   * crypto - Generates a hash made up of 40 letters and digits
   * by passing a source variable through a custom algorithm.
   * First it determines the CRC32, customizable crypt, and MD5
   * hashes for the source variable, and implodes them into one
   * string. This string can be seperated by another customizable
   * salt variable. Finally the SHA-1 hash of the original source
   * variable is calculated, with the imploded string appended
   * to the end of the source variable.
   */
  function crypto($source){
       $salt[0] = "something  here!";   // Limit this to 16 characters
       $salt[1] = "abcd";             // Limit this to 8 characters
       $crypt[0] = crc32($source);
       $crypt[1] = crypt($source, $salt[0]);
       $crypt[2] = md5($source);
       $crypt = implode($salt[1], $crypt);
       return sha1($source.$crypt);
   }
It works really well if you need a secure, custom hashing function. I hope it works for whatever you use it for!


rick.gaither

This is a nifty function to help in securing your web-forms.
If no argument is passed the function will return an encrypted hex code representing the second it was called. If the same hex code is passed to the function it will return the number of seconds that have elapsed. The php script can then check the time between accessing the web-page and submitting the POST. This thwarts script ran web-form submissions. The program can verify a suitable period has elapsed for expected manual entries. The time check can be from 1 second to about 17 hours.
The function requires the latest PEAR Blowfish Encryption module.
This would go in the form:
<?php  print "<input type='hidden' value='" . FormTimer() . "' name='FormCode'>";  ?>
This would go in the main php (post) script:
<?php
$seconds = FormTimer($_POST['FormCode']);
if (($seconds < 10) || ($seconds > 1900)) { die "Your entry time took less than 10 seconds or more than 30 minutes"; }
?>
Function...
<?php
function FormTimer($CodeID="") {
require ('Blowfish.php');
require ('Blowfish/DefaultKey.php');
$key = "Secret^Word";
$bf = new Crypt_Blowfish($key);
$current = substr(sprintf("%d", (time()+1)),-8);
if (!$CodeID) { return bin2hex($bf->encrypt($current)); }
$len = strlen($CodeID); $cValue = -1;
for ($i=0;$i<$len;$i+=2) $Crypt.=chr(hexdec(substr($CodeID,$i,2)));
if ($Crypt) {
$time_called = $bf->decrypt($Crypt);
if ($time_called) { $cValue = (intval($current) - intval($time_called)); }
}
return $cValue;
}
?>


jlinkels

The PHP MD5() function does not encrypt a string in the same way as the standard *nix MD5SUM function.
If you want to access an encrypted string in a  MySQL database from different programs in *nix, and also from PHP, use the MySQL MD5() function, as in:
UPDATE users SET pwd=md5('mypass') WHERE user='myuser';
This will generate the same encrypted string as in PHP md5('mypass').
I am sure it has some security issues, especially if the traffic between the other application and MySQL can be eavesdropped, but for simple encrypted storage it works fine.


tszming

The following method, is about 3x faster than md5('apple');
$hash = bin2hex( md5('apple', true) ) ;


marzetti dot marco

The complement of raw2hex
<?php
function hex2raw( $str ){
 $chunks = str_split($str, 2);
 for( $i = 0; $i < sizeof($chunks); $i++ ) {
$op .= chr( hexdec( $chunks[$i] ) );
}
return $op;
}
?>


brian_bisaillon

Source code to create SSHA passwords...
public function HashPassword($password)
{
 mt_srand((double)microtime()*1000000);
 $salt = mhash_keygen_s2k(MHASH_SHA1, $password, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
 $hash = "{SSHA}".base64_encode(mhash(MHASH_SHA1, $password.$salt).$salt);
 return $hash;
}
Source code to validate SSHA passwords...
public function ValidatePassword($password, $hash)
{
 $hash = base64_decode(substr($hash, 6));
 $original_hash = substr($hash, 0, 20);
 $salt = substr($hash, 20);
 $new_hash = mhash(MHASH_SHA1, $password . $salt);
  if (strcmp($original_hash, $new_hash) == 0)
    ... do something because your password is valid ...
 else
   echo 'Unauthorized: Authorization has been refused for the credentials you provided. Please login with a valid username and password.';
   ... be sure to clear your session data ...
}
Note: The format is compatible with OpenLDAP's SSHA scheme if I'm not mistaken.


dionyziz

Sometimes it's useful to get the actual, binary, md5 digest.
You can use this function for it:
<?php
function md5bin( $target ) {
   $md5 = md5( $target );
   $ret = '';
   for ( $i = 0; $i < 32; $i += 2 ) {
       $ret .= chr( hexdec( $md5{ $i + 1 } ) + hexdec( $md5{ $i } ) * 16 );
   }
   return $ret;
}
?>


eric

Setting raw_output to TRUE has the same effect using pack('H*', md5($string)) in php 4
pack( 'H*' , md5( $string) ) ) == md5($string, TRUE)


jon watte

Scrambling the md5 adds no security, because it only adds obscurity. md5 is a reasonably strong hash function, although it's recently been shown to be weaker than previously thought. If hashing your password with md5 isn't good enough for you, then you should use a stronger hash like Tiger instead -- not apply amateurish obfuscation that only serves to give you a false sense of security.
I don't know of an implementation of Tiger for PHP, but the algorithm is pretty simple (and secure) so you could probably write it in plain PHP code.


karig

Scramble your hashes.
If you are worried about whether these hash functions are "good enough" for security and are tempted to combine hash functions to try to increase security, but you know that combining hashes might be counterproductive, then why not use md5() to get your hash string, then use a custom scramble function to rearrange the digits in that hash string?
Use this scramble function whenever a user is logging in: Encrypt the password with md5(), then with your scramble function, and compare the result with the pre-encrypted password stored on your server for that user.
Here is an example (you might decide to scramble the digits in a different order):
<?php
function scramble($p) {
   // Assumes that $p is going to be 32 characters long
   $q = $p{13} . $p{30} . $p{5} . $p{17} . $p{23} . $p{0}
       . $p{28} . $p{4} . $p{18} . $p{25} . $p{6} . $p{20}
       . $p{14} . $p{9} . $p{31} . $p{11} . $p{24} . $p{29}
       . $p{10} . $p{3} . $p{15} . $p{26} . $p{8} . $p{12}
       . $p{21} . $p{27} . $p{1} . $p{16} . $p{22} . $p{7}
       . $p{19} . $p{2};
   return $q;
}
$p = $_POST['password'];
// If the password is blank or too short, do something here.
$p = scramble(md5($p));
// Now set $s = scrambled password stored on server.
// If $p == $s then we have a match.
?>
You could even make the scramble function more elaborate by repeating certain arbitrary characters an arbitrary number of times, e.g., having scramble() insert $p(19) into $q three or four times, thus producing a string longer than 32 characters.


tommiboy

Regarding those many posts about MD5 and this-or-that hash function being "broken" or insecure because it has collisions, please note the following:
1. Every hash function has collisions, that is what hash functions are made for. MD5, as an example, turns N bits of input into 128 bits of output. Obviously, whenever N > 128 bits, then there MUST be collisions. This does not mean the function is broken, it means that the function does EXACTLY what you want it to do - it makes a secret unrecoverable.
The important thing about "secure" hash functions is that it is hard to calculate an input that will produce a certain output (e.g. the same output as another user's password). It is impossible to reconstruct a password from a hash if the password has more than 128 bits since several passwords necessarily map to the same hash. No matter which supercomputers you use, you have a set of equations with several unknowns. It is possible to find SOME password that produces a valid hash, though.
For every reasonable scenario, however, MD5 will do just fine. If you are concerned, store the password length as well.
2. Chaining the hash function means 128 bits of input producing 128 bits of output, this does not make sense, really. In fact, you greatly increase the likelihood of finding SOME password that produces the same double-hash.
3. Chaining MD5 with SHA makes little sense, too, as you feed 128 bits into a function that returns 256 bits. So the information that you keep around is 50% redundant. Security is in no way enhanced.
4. You can add "salt", i.e. a constant or variable string (for example calculated from the user id) that is concatenated to the input of the hash function, but that does not really make things a lot better. It does make a dictionary attack against a stolen password database harder, if nothing else.
5. Concerns about this-or-that hash being not good enough are rather silly since there are a lot of other ways which are by several orders of magnitude cheaper and easier to break into your system. It is not likely that any sane person will attempt to find collisions of a hash function to break into one single account. Users are only too happy to give out their password to "the administator who must verify that their password is correct".
6. What happens if two users accidentially choose passwords that have a hash collision? First, this will probably never happen, and second, if it does happen, then there is not much harm. Two users can have the same password and none of them will ever notice.


squeegee

Regarding the md5_base64 function posted below, since the encoded string will never be longer than 64 characters (the maximum length of a base64 encoded line), and the fact that base64 strings only insert the '=' pad character at the end of an encoded line, instead of using preg_replace, you can just use rtrim.
$myhash=rtrim(base64_encode(pack("H*",md5($data))),"=");
This will result in a string of 22 characters, suitable for inserting in mysql or whatever. Also, if you are testing against the string in a query in mysql, make sure to use the keyword BINARY, as case matters.
The reason for the function in the first place (for me):
If you're currently using an md5 hash for a unique index, this will save at least 20 bytes for every record on disk (index + data) and 10 bytes in memory. If you have millions of rows, that can really add up (100 million rows would require about 1 less gigabyte of memory for your key_buffer_size variable in mysql).


santa cruz skelly

Re: public at kreinacke dot com
It has long been a point of frustration to me that md5() functions don't produce the same results as the *nix md5sum program. Reading your comments about the incongruity today pushed me over the edge to finally understand why. The answer, I believe I have found, is that md5sum includes an extra newline as the termination of the file content. ugh.
In response I have produced the following function that, at least on my server, produces a result matching the output of md5sum on the command line:
function md5sum($str) { return(md5($str . "\n")); }
Yes, that easy.
My results from typing the string "apples and oranges" into a PHP script using that function and the same string entered into a file on disk using md5sum on the command line to pull it return:
6c1111418017a050006eee9f2bdda2bf
Your `echo -n "apples and oranges | md5sum` method (which suppresses that newline I refer to!) and PHP's normal md5() function also return the same result as one another as you described, but those are string based operations. My solution is a function that reproduces the result of md5sum's assessment of on-disk data based on the contents of the file being in a string, something that's critical to my application.


mina86

Re: Andrew Nelless
I believe that HMAC was designed for some reason. I believe the reason was that <?php hmac_md5($salt, $password); ?> is more secure then <?php md5($salt . $password); ?>
Re: nathan at nathanbolender dot com
The 'Salt & Pepper Encrypter' is no more secure then standard sha1() function. It only adds some random chars to the hash but does nothing with the password's hash. In particular, its enought to remove 32 or 40 characters (depending on the length of the whole hash - 74 or 82 characters acordingly) from the hash starting with the character at position stored at the end of hash (last two digits). We get a 42-char long string which first 40 characters are SHA-1 of the password.


public

PHP's md5() function returns the exact same hash value as MySQL's MD5() function and other than stated before as the md5sum command line tool on most Linux/UNIX systems.
Note that trailing line feeds do matter, when you apply md5sum on a text file:
shell> php -r 'echo md5("test");'
--> 098f6bcd4621d373cade4e832627b4f6
mysql> select md5('test');
--> 098f6bcd4621d373cade4e832627b4f6
shell> echo -n test | md5sum
--> 098f6bcd4621d373cade4e832627b4f6
In the third example, note the '-n' option, which prevents echo from appending a line feed.


mina86

It seems that the best solution would be to use HMAC-MD5. An implementation of HMAC-SHA1 was posted by mark on 30-Jan-2004 02:28 as a user comment to sha1() function (-> http://php.net/manual/function.sha1.php#39492). Here's how it would look like (some other optimizations/modifications are included as well):
<?php
// Calculate HMAC according to RFC2104
// http://www.ietf.org/rfc/rfc2104.txt
function hmac($key, $data, $hash = 'md5', $blocksize = 64) {
 if (strlen($key)>$blocksize) {
   $key = pack('H*', $hash($key));
 }
 $key  = str_pad($key, $blocksize, chr(0));
 $ipad = str_repeat(chr(0x36), $blocksize);
 $opad = str_repeat(chr(0x5c), $blocksize);
 return $hash(($key^$opad) . pack('H*', $hash(($key^$ipad) . $data)));
}
// Remember to initialize MT (using mt_srand() ) if required
function pw_encode($password) {
 $seed = substr('00' . dechex(mt_rand()), -3) .
   substr('00' . dechex(mt_rand()), -3) .
   substr('0' . dechex(mt_rand()), -2);
 return hmac($seed, $password, 'md5', 64) . $seed;
}
function pw_check($password, $stored_value) {
 $seed = substr($stored_value, 32, 8);
 return hmac($seed, $password, 'md5', 64) . $seed==$stored_value;
}
// Test
$password = 'foobar';
$encoded  = pw_encode($password);
$result   = pw_check ($password, $encoded) ? 'true' : 'false';
echo<<<END
password: $password
encoded : $encoded
rsult   : $result
END;
?>


sebastian dot haller

It has been found, that hash('md5', 'string'); is faster than md5($string):
http://www.php.net/manual/en/function.hash.php


anonymous

In response to the person who suggested concatenation of hashes, I believe that the hashing of a hash would be a better option.
$str = "secret";
$doublehash = sha1(md5($str));


ircmaxell

In Response To AzuMao
I did some speed tests (1000 repetitions), and my results are slightly different (php 5.2.2).  Here's what I got for string 'string' (6 characters):
0.0065789222717285- MD5
0.0078611373901367- SHA1
0.00068497657775879- CRC32
0.0021169185638428- HASH(md5)
0.0026431083679199- HASH(sha1)
0.0014209747314453- HASH(CRC32)
for a 14000 character string however (a standard HTML page), here's the results
0.08871603012085- MD5
0.21350693702698- SHA1
0.062330007553101- CRC32
0.083562850952148- HASH(md5)
0.2072479724884- HASH(sha1)
0.060271978378296- HASH(CRC32)
So actually So actually, MD5 is significantly more efficient than SHA1.  Not to mention, that hash(func) seems to be faster than func...


mina86

In respons to Emin Sadykhov at 14-Oct-2003 12:47:
The function presented by Emin isn't IMO simple, simpler is:
<?php
if (!function_exists('is_md5')) {
 function is_md5($var) {
   return preg_match('/^[A-Fa-f0-9]{32}$/',$var);
 }
}
?>
Morover (as I proved somewhere else) it's faster 'cuz preg_match() is faster then ereg()


nathan

If you're a security freak you might want to take a look at the 2 functions I have posted at http://code.nathanbolender.com/PHP/salt_pepper/ . It uses a hardcoded "key" and hashes it one of 2 ways, so you are always left with a random 'hash' to store in your database. The other function will check the hash against the original string to make sure that it is correct. If you want to see an example of the debug output you can at http://code.nathanbolender.com/PHP/salt/ . Note that on that page the "key" is random only to demonstrate the possibility for so much variations.
I know that a simple md5() would normally be enough, but I came up with this and I wanted to share it.


john s.

If you want to replicate CPAN Digest::MD5's function md5_base64 in PHP, use this code:
<?php
function md5_base64 ( $data )
{
   return preg_replace('/=+$/','',base64_encode(pack('H*',md5($data))));
}
?>


coryostrudel

If you are storing your passwords with and MD5 hash and are worried about collisions, an approach I have used was to store two passwords for the user.
credentials
----------
userName
password
passwordChk
Where:
$input - users input password
$key - a site based key stored out of public folders
password = MD5($key.strrev($input))
passwordChk = MD5($input{0}.substr($input,(floor(strlen($input))/2),strlen))
This will stored the users password in the database as an MD5 hash of the string reversed plus a site based key stored out of public folders.
It also stores a check value to check that the input is the true input and not a colliding value.  The check takes the first character appends a substring of the input taking the last half of the input string and creates and MD5.
I think this is pretty secure.  It takes a modified salt & pepper approach, and follows up with a check on the original input to make sure it is not a colliding value, while also not storing the original password in plain text.


gigabyte0

I would think that this would create a slightly mode secure hash by using this:
<?php
function hash($text){
$hashtext = "string";
return md5($text.$hashtext)
}
?>
If you can keep the $hashtext secure.


prodigysim

I ran a small speed test of my own based on comments by sebastian dot haller at freesurf dot ch and tszming at gmail dot com.
bin2hex(md5('string', true)) performs faster than md5('string').
However, this binary speed boost does not apply for the hash() function.
<?php
$time=microtime(1);
for ($i=0;$i<100000;$i++)
  hash('md5', 'string');
echo microtime(1)-$time,': hash/md5
';
$time=microtime(1);
for ($i=0;$i<100000;$i++)
  md5('string');
echo microtime(1)-$time,': md5
';
$time=microtime(1);
for ($i=0;$i<100000;$i++)
  bin2hex(hash('md5', 'string', TRUE));
echo microtime(1)-$time,': bin/hash/md5
';
$time=microtime(1);
for ($i=0;$i<100000;$i++)
  bin2hex(md5('string', TRUE));
echo microtime(1)-$time,': bin/md5
';
?>
Returns:
0.392316102982: hash/md5
0.725342035294: md5
0.421605110168: bin/hash/md5
0.483132839203: bin/md5


seth

I made this simple script to beat MD5 crackers and it worked, so have fun. Its simple and effective.
<?php
$pass = str_split("mypassword");
foreach ($pass as $hashpass) {
$majorsalt .= md5($hashpass);
}
$corehash = md5($majorsalt);
echo $corehash;
?>
Tested against rednoise and gdata md5 crackers.


me

i made a php script that can guess a hashed string's value, but it takes forever with more than 2 characters in the password
<?php
set_time_limit(0);
$randpass = chr(rand()).chr(rand());
print "RANDOM PASSWORD: $randpass";
print "<br/>";
$password = md5("$randpass");
$guesswrd = "";
$tries = 0;
$start = microtime(true);
while($password != md5($guesswrd)){
$guesswrd = chr(rand()).chr(rand());
$tries+=1;
}
$end = microtime(true);
$time = $end-$start;
print "GUESSED PASSWORD: $guesswrd";
print "<br/>";
print "It took $tries tries and $time seconds";
?>


mark a t metrofindings dto com

Here's a better password checker that tries to guess the password in a certain order.  I found that the random guess ones would never do anything more than 3-4 characters because random guesses are never guaranteed to touch all the guesses.
This is a sequential password guesser, it needs to know the length of the target password.  Maybe someone can add on variable length passwords.  All you have to do is adjust the fingerprint size and reset it to all zeros.
it can guess "foo" as the password in 6 seconds on 1.7Ghz athlon (bogomips: 3504)
<?php
set_time_limit(0);
$_GET['password'] = $argv[1];
$_GET['length'] = @$argv[2];
function randomkeys($length)
{
    $pattern =
"1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $pattern .= "abcdefghijklmnopqrstuvwxyz";
    $key  = $pattern{rand(0,61)};
    for($i=1;$i<$length;$i++)
    {
        $key .= $pattern{rand(0,61)};
    }
    return $key;
}
function getpwguess($length, &$fingerprint) {
static $allchars = array(
'1','2','3','4','5','6','7','8','9','0',
'a','b','c','d',
'e','f','g','h','i','j',
'k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','A','B','C',
'D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z');
$guess = array();
$next = false;
foreach ($fingerprint as $index => $fing) {
if ($next == true) {
$fingerprint[$index]++;
$fing++;
$next = false;
}
if ($fing == 62) {
$fingerprint[$index] = 0;
$fing = 0;
$next = true;
$guess[]  = $allchars[$fing];
continue;
}
$guess[]  = $allchars[$fing];
}
$fingerprint[0]++;
return implode('',$guess);
}

if (isset($_GET['password'])){
$password = $_GET['password'];
$password_length = strlen($password);
}
else
{
$password_length = 3;
if (isset($_GET['length'])){
$password_length = $_GET['length'];}
$password = randomkeys($password_length);
}

echo "Password is: $password \n";
$password = md5($password);
$attempts = 0;
$start = microtime(true);
$guess = '';
$fingerprint = array();
for ($x=0; $x < $password_length; $x++) {
$fingerprint[$x] = 0;
}
while ($password != $guess){
$rndm = getpwguess($password_length,$fingerprint);
$guess = md5($rndm);
$attempts++;
//echo "tried $rndm... (skipping 100)\r\n";
if ($attempts % 1000 ==0 ) {
echo "tried $rndm... (skipping 1000)\r\n";
}
//if the last bucket is 62, then we've tried them all
if ($fingerprint[ ($password_length-1)] == 62) {
echo "Tried every combination, maybe password isn't ".$password_length." chars long?\n";
//here is where you would increase password length, re-init fingerprint array
//  if you didn't know the target length.
}
}
$end = microtime(true);
$time = $end-$start;
echo "Password guessed ('".$rndm."') correctly after $attempts attempts and $time seconds";
?>
This code was modified from other people work.  I'm not certain what kind of license it's under, I would vote for BSD.


functionifelse

Here is a function to convert raw md5 to hex md5:
<?
function raw2hex($s){
 for($i = 0; $i < strlen($s); $i++){
   $op .= str_pad(dechex(ord($s[$i])),2,"0",STR_PAD_LEFT);
 }
 return $op;
}
?>
Where $s is the raw md5 input.


azumao

Here is a far more accurate test if you are not going to be doing it over and over.
<?php
$time=microtime(1);
hash('md5', 'string');
echo (microtime(1)-$time)*10000,': hash/md5
';
$time=microtime(1);
md5('string');
echo (microtime(1)-$time)*10000,': md5
';
$time=microtime(1);
hash('sha1', 'string');
echo (microtime(1)-$time)*10000,': hash/sha1
';
$time=microtime(1);
sha1('string');
echo (microtime(1)-$time)*10000,': sha1
';
?>
Outputs
0.11920928955078: hash/md5
0.090599060058594: md5
0.14066696166992: hash/sha1
0.050067901611328: sha1
Refresh it a few times and you will see that it is indeed consistant. sha1 is faster if you are not going to be using it over and over. I'm using this for etags in PHP and only need to use it once, so for me sha1 is faster.
Note that these times are all times by 10000 so that it shows up as a real number instead of something like
1.1920928955078E-5: hash/md5
8.1062316894531E-6: md5
1.4066696166992E-5: hash/sha1
5.9604644775391E-6: sha1
(to negative powers)


terry _at_ scribendi_com

Do not use the hex strings returned by md5() as a key for MCrypt 256-bit encryption.  Hex characters only represent four bits each, so when you take 32 hex characters, you are only really using a 128-bit key, not a 256-bit one.  
Using an alphanumeric key generator [A-Za-z0-9] will also only provide a 192-bit key in 32 characters.
Two different MD5s concatenated in raw binary form, or mcrypt_create_iv(32,MCRYPT_DEV_RANDOM) will give you a true 256-bit key string.


ian

Concatenating two different hashes will decrease security.  Instead of an attacker having to crack one hash algorithm they now have the option of cracking either.  It's like a crime scene having one clue or several clues.  In security simplicity is usually the better approach.

helpful harry

check out these functions to fake a sha1 entry using md5.  Very, very secure if attackers get your password file...
also, it encrypts differently for the same string, every time
function pw_encode($password)
{
  for ($i = 1; $i <= 8; $i++)
  $seed .= substr('0123456789abcdef', rand(0,15), 1);
  return md5($seed.$password).$seed;
}
function pw_check($password,$stored_value)
{
  $stored_seed = substr($stored_value,32,8);
  if (md5($stored_seed.$password).$stored_seed == $stored_value)
     return TRUE;
  else
     return FALSE;
}


alexander valyalkin

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";
?>


nicholas

Agreed, tszming at gmail dot com. I did my own test using simple (letters) and complex (letters, numbers, symbols) strings of short, (6 characters), medium (a sentence), and long (three paragraphs) lengths. Overall, using
<?php
echo bin2hex( md5( $str, TRUE ) );
?>
versus just
<?php
echo md5( $str );
?>
ranges between 2x and 3x faster and yet return identical results. Good catch.


silasjpalmer

A user friendly example of hkmaly's XOR encryption / decryption functions which use MD5 hashing on the key.
<?php
 function bytexor($a,$b,$l)
 {
   $c="";
   for($i=0;$i<$l;$i++) {
     $c.=$a{$i}^$b{$i};
   }
   return($c);
 }
 function binmd5($val)
 {
   return(pack("H*",md5($val)));
 }
 function decrypt_md5($msg,$heslo)
 {
   $key=$heslo;$sifra="";
   $key1=binmd5($key);
   while($msg) {
     $m=substr($msg,0,16);
     $msg=substr($msg,16);
     $sifra.=$m=bytexor($m,$key1,16);
     $key1=binmd5($key.$key1.$m);
   }
   echo "\n";
   return($sifra);
 }
 function crypt_md5($msg,$heslo)
 {
   $key=$heslo;$sifra="";
   $key1=binmd5($key);
   while($msg) {
     $m=substr($msg,0,16);
     $msg=substr($msg,16);
     $sifra.=bytexor($m,$key1,16);
     $key1=binmd5($key.$key1.$m);
   }
   echo "\n";
   return($sifra);
 }
// Example of usage...
$message = "This is a very long message, but it is very secret and important
and we need to keep the contents hidden from nasty people who might want to steal it.";
$key = "secret key";
$crypted = crypt_md5($message, $key);
echo "Encoded = $crypted
"; // returns ¦ý¼=¯ ¶òº


the-master

@ me at dontemailme dot com
Your code takes ages to run mainly because it uses totally random characters, which in some cases don't exist because you have used chr() and rand() which can output very large numbers.
I think most people only use alphanumeric passwords so here is a code which is far quicker.  Where yours took 16 seconds mine took 2.  It still takes ages for large passwords though which is reassuring!  Also a hacker shouldn't know the password length meaning that the passwords are very secure with hashing.
<?php
set_time_limit(0);
function randomkeys($length)
{
   $pattern = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   $key  = $pattern{rand(0,61)};
   for($i=1;$i<$length;$i++)
   {
       $key .= $pattern{rand(0,61)};
   }
   return $key;
}
if (isset($_GET['password'])){
$password = $_GET['password'];
$password_length = strlen($password);
}
else
{
$password_length = 3;
if (isset($_GET['length'])){
$password_length = $_GET['length'];}
$password = randomkeys($password_length);
}
echo "Password is: $password <br />";
$password = md5($password);
$attempts = 0;
$start = microtime(true);
while ($password != $guess){
$guess = md5(randomkeys($password_length));
$attempts++;
}
$end = microtime(true);
$time = $end-$start;
echo "Password guessed correctly after $attempts attempts and $time seconds";
?>
I think this code is correct but hopefully someone will tell me if it isn't or change it.


hans

http://md5.rednoize.com offers a service to reverse engineer md5 hashes. Very useful if you got a md5 hash and need the plain text string of this md5 hash. The website has currently over 47 million hashes stored. It also has support for SHA-1 hashes.

andrew nelless anelless _ gmail _com

"mina86 at tlen dot pl"'s (19-Sept-05) HMAC-MD5 implementation is correct but his example usage provides little practical advantage over the simple concatenation and hash approach to salting.
$hash = md5($salt . $password);
On the other hand, a good use for a MAC (with a server side private key) would be to store one in the users cookie in order to verify that cookie's (or parts of them) you issue haven't been changed manually (or for that matter, by any other website (maybe via a XSS browser exploit?), MITM attack or evil proxy).
Such a trick allows you to put mildly critical data about a user, that you don't want changed by anyone but you, in their cookie rather than in your database. This could have advantages (openness, not needing to store user email addresses at the server side once they have been verified by email, even do away with the need to store data about a poster in a server side database altogether but still being able to allow these almost anonymous posters to come along and edit their submissions with confidence) and be rather entertaining (users trying to crack their cookie code to elevate their stats and/or permissions).
This is like issueing a passport. The traveller can see all of it,  get it stamped (~customise parts of it) but can also invalidate it and have it revoked. It can also save on expensive and time consuming nationality/immigration checks (~using the database) at the airport (~the server side).


Change Language


Follow Navioo On Twitter
addcslashes
addslashes
bin2hex
chop
chr
chunk_split
convert_cyr_string
convert_uudecode
convert_uuencode
count_chars
crc32
crypt
echo
explode
fprintf
get_html_translation_table
hebrev
hebrevc
html_entity_decode
htmlentities
htmlspecialchars_decode
htmlspecialchars
implode
join
levenshtein
localeconv
ltrim
md5_file
md5
metaphone
money_format
nl_langinfo
nl2br
number_format
ord
parse_str
print
printf
quoted_printable_decode
quotemeta
rtrim
setlocale
sha1_file
sha1
similar_text
soundex
sprintf
sscanf
str_getcsv
str_ireplace
str_pad
str_repeat
str_replace
str_rot13
str_shuffle
str_split
str_word_count
strcasecmp
strchr
strcmp
strcoll
strcspn
strip_tags
stripcslashes
stripos
stripslashes
stristr
strlen
strnatcasecmp
strnatcmp
strncasecmp
strncmp
strpbrk
strpos
strrchr
strrev
strripos
strrpos
strspn
strstr
strtok
strtolower
strtoupper
strtr
substr_compare
substr_count
substr_replace
substr
trim
ucfirst
ucwords
vfprintf
vprintf
vsprintf
wordwrap
eXTReMe Tracker