php md5加密

变换一:循环MD5
  最容易理解的变换就是对一个密码进行多次的MD5运算。自定义一个函数,它接受$data和$times两个形参,第一个是要加密的密码,第二个是重复加密的次数。实现这种变换有两种算法——
<?php
//迭代算法
function md5_1_1($data, $times = 32)
{
//循环使用MD5
for ($i = 0; $i < $times; $i++) {
$data = md5($data);
}
return $data;
}

//递归算法
function md5_1_2($data, $times = 32)
{
if ($times > 0) {
$data = md5($data);
$times--;
return md5_1_2($data, $times); //实现递归
} else {
return $data;
}
}
?>

变换二:密文分割MD5
<?php
//把密文分割成两段,每段16个字符
function md5_2_1($data)
{
//先把密码加密成长度为32字符的密文
$data = md5($data);
//把密码分割成两段
$left = substr($data, 0, 16);
$right = substr($data, 16, 16);
//分别加密后再合并
$data = md5($left).md5($right);
//最后把长字串再加密一次,成为32字符密文
return md5($data);
}

//把密文分割成32段,每段1个字符
function md5_2_2($data)
{
$data = md5($data);
//循环地截取密文中的每个字符并进行加密、连接
for ($i = 0; $i < 32; $i++) {
$data .= md5($data{$i});
}
//这时$data长度为1024个字符,再进行一次MD5运算
return md5($data);
}
?>

 
变换三:附加字符串干涉
<?php
//附加字符串在原数据的尾部
function md5_3_1($data, $append)
{
return md5($data.$append);
}

//附加字符串在原数据的头部
function md5_3_2($data, $append)
{
return md5($append.$data);
}

//附加字符串在原数据的头尾
function md5_3_3($data, $append)
{
return md5($append.$data.$append);
}
?>

变换四:大小写变换干涉
  由于PHP所提供的md5()函数返回的密文中的英文字母全部都是小写的,因此我们可以把它们全部转为大写,然后再进行一次MD5运算。

<?php
function md5_4($data)
{
//先得到密码的密文
$data = md5($data);
//再把密文中的英文母全部转为大写
$data = strtotime($data);
//最后再进行一次MD5运算并返回
return md5($data);
}
?>

变换五:字符串次序干涉
  把MD5运算后的密文字符串的顺序调转后,再进行一次MD5运算。

<?php
function md5_5($data)
{
//得到数据的密文
$data = md5($data);
//再把密文字符串的字符顺序调转
$data = strrev($data);
//最后再进行一次MD5运算并返回
return md5($data);
}
?>

  MD5变换算法是数之不尽的,甚至无须自己再去创造,就用上面的五个互相组合就可以搞出很BT的算法。比如说先循环加密后再分割,并在每一段上附加一个字符串再分别加密,然后变换大小写并颠倒字符串顺序后连成一个长字符串再进行MD5运算……
  如果真的很不幸,由于某些漏洞,比如说SQL Injection或者文件系统中的数据库被下载而异致用户密码数据暴露,那么MD5变换算法就能大大地增加破译出密码原文的难度,首先就是使网上很多的MD5原文/密文对照数据库(要知道,这是破译MD5最高效的方法)没有用了,然后就是使攻击者用常规算法去穷举一串由变换算法得到的密文而搞得焦头烂额。当然,MD5变换算法特别适合用于非开源的Web程序使用,虽说用在开源的程序中优势会被削弱(大家都知道算法),但是也能抑制MD5原文/密文对照数据库的作用。要进行这些复杂的变换运算,当然就要花费的更多的系统开销了,然而对于安全性要求很严格的系统来说,多付出一些来换取高一点的安全性,是完全值得的。

md5
(PHP 3, PHP 4, PHP 5)

md5 -- Calculate the md5 hash of a string
Description
string md5 ( string str [, bool raw_output] )


Calculates the MD5 hash of str using the RSA Data Security, Inc. MD5 Message-Digest Algorithm, and returns that hash. The hash is a 32-character hexadecimal number. If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16.
注: The optional raw_output parameter was added in PHP 5.0.0 and defaults to FALSE
例子 1. A md5() example
<?php
$str = 'apple';

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


See also crc32(), md5_file(), and sha1().

add a note User Contributed Notes
tszming at gmail dot com
31-Oct-2006 12:47
The following method, is about 3x faster than md5('apple');

$hash = bin2hex( md5('apple', true) ) ;
squeegee
11-Oct-2006 01:01
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).
maximius at gmail dot com
09-Oct-2006 01:38
This is just something I made while looking into MD5 and SHA-1, how they can be exploited, and whatnot.

/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);
}


<?php
$pass = str_split("mypassword");
foreach ($pass as $hashpass) {
$majorsalt .= md5($hashpass);
}
$corehash = md5($majorsalt);
echo $corehash;
?>

----------
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))

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

?>
mina86 at projektcode dot org
25-Jan-2006 04:01
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 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;
}
?>
Andrew Nelless ( anelless _ gmail _com )
18-Dec-2005 02:04
"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).
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.
?>

Here's how it would look like (some other optimizations/modifications are included as well):
<?php
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;
?>
eric at opelousas dot org
01-Aug-2005 05:57
Setting raw_output to TRUE has the same effect using pack('H*', md5($string)) in php 4

pack( 'H*' , md5( $string) ) ) == md5($string, TRUE)
Helpful Harry
01-Jul-2005 02:29
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;
}
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.
gigabyte0 at NOSPAM dot gmail dot com
07-Mar-2005 03:22
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.
Anonymous
20-Feb-2005 08:06
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));
ian at ianalbert dot com
17-Feb-2005 04:41
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.
functionifelse at gmail dot com
10-Dec-2004 12:34
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.
John S.
04-Dec-2004 03:42
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))));
}

?>
Alexander Valyalkin
01-Jul-2004 04: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";

?>
mina86 at tlen dot pl
27-Feb-2004 03:14
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()
brian_bisaillon at rogers dot com
26-Feb-2004 12:17
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.
silasjpalmer at optusnet dot com dot au
14-Feb-2004 12:17
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<BR>"; // returns = ` < H {.1{ JV+je

$uncrypted = decrypt_md5($crypted, $key);
echo "Unencoded = $uncrypted"; // returns This is a very long message (etc)

?>
mina86 at tlen dot pl
13-Sep-2003 08:41
In respons to paj at pajhome dot org dot uk @ 21-May-2003 03:20:
In many cases, there is only hash of password saved on server, so JavaScript script must return: md5(md5(password) + random) and server must compare it with md5(saved_md5 + random).
However, it might be less secure then sending plain password. Let say someone gaind read only access to your database (it doesn't matter how he did it). With such access he can read each user's reacord so he knows each user username and hash of password. With that knowledge, all he must do to hack your site is connect to server, read the random number, calculate md5(hash_of_password_which_he_has_stolen + random) and send it to server. Be aware of this issue if you think your database is not secure enought.
marc at NOSPAM dot giombetti dot com
08-Aug-2003 12:18
I use md5 to create a string that will be valid for X seconds!
One may use this function for cacheing reasons or even timeout functionality in a script.

/**
* valid_for_x_minutes() : Gernates an md5 hash that will be the same for $timeout minutes
* This function was intitialy used in combination with jpGraph to allow cacheing of multiple
* charts for a specified time.
*
* @param $timeout - Timeout in minutes
* @param $optional - An optional string to include to in the md5 string
* @return
*/
function valid_for_x_minutes($timeout,$optional){
if($timeout != "0"){
$hours = date("H");
$minutes = date("i");
$tmpval = ceil($minutes/$timeout)*$timeout;
if(!empty($optional)){
return md5("$tmpval$optional");
}else{
return md5("$tmpval");
}
}else{
return md5(time());
}
}
paj at pajhome dot org dot uk
22-May-2003 06:20
Hi,

From the documentation on Digest::MD5:
md5($data,...)
This function will concatenate all arguments, calculate the MD5 digest of this "message", and return it in binary form.

md5_hex($data,...)
Same as md5(), but will return the digest in hexadecimal form.

PHP's function returns the digest in hexadecimal form, so my guess is that you're using md5() instead of md5_hex(). I have verified that md5_hex() generates the same string as PHP's md5() function.
(original comment snipped in various places)
>Hexidecimal hashes generated with Perl's Digest::MD5 module WILL
>NOT equal hashes generated with php's md5() function if the input
>text contains any non-alphanumeric characters.
>
>$phphash = md5('pa$$');
>echo "php original hash from text: $phphash";
>echo "md5 hash from perl: " . $myrow['password'];
>
>outputs:
>
>php original hash from text: 0aed5d740d7fab4201e885019a36eace
>hash from perl: c18c9c57cb3658a50de06491a70b75cd

simple slappaswd MD5 hash generation:
$ldap_passwd = "{md5}".base64_encode(pack("H*",md5($password)));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值