猿问

验证 md5 base64_encode 以显示值

我正在比较base64_encode md5在不同域上使用相同值(IP、时间、路径和密码)创建的两个密钥。


在第一个域上创建加密密钥


    $secret = "PASSWORD";

    $expires = time()+3600; 

    $uri = '/video1/';

    $ip = $_SERVER['REMOTE_ADDR'];

    $md5 = base64_encode(md5($secret . $expires . $uri . $ip, true)); 

    $md5 = strtr($md5, '+/', '-_'); 

    $md5 = str_replace('=', '', $md5); 

    $rtmp = "?md5=".$md5;

    $urls= 'http://example.com'.$uri .$rtmp;


    echo '<a href="' . $urls . '">' .$urls . '</a>';

在第二个域上创建加密密钥并与收到的 URL 密钥进行比较


    function getAddress() {

        $protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';

        return $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

    }

    $url = getAddress();

    $path = (parse_url($url, PHP_URL_PATH));    // recive path here '/video1/'

    $verify = substr(parse_url($url, PHP_URL_QUERY),4); //recive md5 encoded key from URL 


    /* create again md5 encoded key to match with URL key */

    $secret = "PASSWORD";

    $expires = time()+3600; 

    $uri = $path;

    $ip = $_SERVER['REMOTE_ADDR'];

    $md5 = base64_encode(md5($secret . $expires . $uri . $ip, true)); 

    $md5 = strtr($md5, '+/', '-_'); 

    $md5 = str_replace('=', '', $md5); 

    $rtmp = $md5;


    if ($rtmp===$verify){     // Matching both, local key with URL key

        echo '<h1>Welcome</h1>';

    }

    else {

        echo '<h1>Password,Time,Path or IP Not Match</h1>';

    }

我在加密中使用了 time(3600),所以if语句应该显示 3600 秒的值。但这总是显示else价值。


这将如何打印if时间值(3600)?在那之后打印else


呼如林
浏览 152回答 2
2回答

守着星空守着你

也许超出了问题的范围,但整个MD5方法是有缺陷的,所以为什么不去“全力以赴”(俗话说)并实际使用加密而不是问题中的散列?的encrypt和decrypt在用于PHP手动功能是基于代码中发现openssl_encryptfunction encrypt( $data=false, $pubkey=false, $cipher='AES-128-CBC' ){&nbsp; &nbsp; if( !empty( $data ) && in_array( $cipher, openssl_get_cipher_methods() ) ){&nbsp; &nbsp; &nbsp; &nbsp; $ivlen = openssl_cipher_iv_length( $cipher );&nbsp; &nbsp; &nbsp; &nbsp; $iv = openssl_random_pseudo_bytes( $ivlen );&nbsp; &nbsp; &nbsp; &nbsp; $encrypted = openssl_encrypt( $data, $cipher, $pubkey, $options=OPENSSL_RAW_DATA, $iv );&nbsp; &nbsp; &nbsp; &nbsp; $hash = makehash( $encrypted, $pubkey );&nbsp; &nbsp; &nbsp; &nbsp; return base64_encode( $iv . $hash . $encrypted );&nbsp; &nbsp; }&nbsp; &nbsp; return false;}function decrypt( $data, $pubkey=false, $cipher='AES-128-CBC' ){&nbsp; &nbsp; if( !empty( $data ) && in_array( $cipher, openssl_get_cipher_methods() ) ){&nbsp; &nbsp; &nbsp; &nbsp; $shalength=32;&nbsp; &nbsp; &nbsp; &nbsp; $data = base64_decode( $data );&nbsp; &nbsp; &nbsp; &nbsp; $ivlen = openssl_cipher_iv_length( $cipher );&nbsp; &nbsp; &nbsp; &nbsp; $iv = substr( $data, 0, $ivlen );&nbsp; &nbsp; &nbsp; &nbsp; $hash = substr( $data, $ivlen, $shalength );&nbsp; &nbsp; &nbsp; &nbsp; $encrypted = substr( $data, $ivlen + $shalength );&nbsp; &nbsp; &nbsp; &nbsp; $decrypted = openssl_decrypt( $encrypted, $cipher, $pubkey, $options=OPENSSL_RAW_DATA, $iv );&nbsp; &nbsp; &nbsp; &nbsp; if( $decrypted && hash_equals( $hash, makehash( $encrypted, $pubkey ) ) ){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $decrypted;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return false;}function makehash( $data, $key ){&nbsp; &nbsp; return hash_hmac( 'sha256', $data, $key, true );}然后,使用它:$lifetime=3600;$key='A complex secret string - ideally this will be the contents of an ssl cert perhaps obtained using file_get_contents etc';$cipher='AES-128-CBC';/* Create the payload of items to be encrypted and passed in the url */$payload=array(&nbsp; &nbsp; 'endpoint'&nbsp; =>&nbsp; '/secret-forum/topic404',&nbsp; &nbsp; 'expires'&nbsp; &nbsp;=>&nbsp; time() + $lifetime,&nbsp; &nbsp; 'ip'&nbsp; &nbsp; &nbsp; &nbsp; =>&nbsp; $_SERVER['REMOTE_ADDR']);/* create a nice string to be encrypted */$data=urldecode( http_build_query( $payload ) );/* create the encrypted data string */$encrypted=encrypt( $data, $key, $cipher );/* construct the url to be presented to the user */$url=sprintf( '%s://%s/?hash=%s', $_SERVER['REQUEST_SCHEME'], $_SERVER['HTTP_HOST'], $encrypted );printf('<a href="%1$s" target="_blank">%1$s</a>', $url);/* At the Server - To process the url and check validity */$querystring = parse_url( $url, PHP_URL_QUERY );if( !empty( $querystring ) ){&nbsp; &nbsp; list( $param, $data )=explode( '=', $querystring );&nbsp; &nbsp; /* decrypt data */&nbsp; &nbsp; $decrypted=decrypt( $data, $key, $cipher );&nbsp; &nbsp; if( $decrypted ){&nbsp; &nbsp; &nbsp; &nbsp; /* process initial querystring we created - create an array $out */&nbsp; &nbsp; &nbsp; &nbsp; parse_str( $decrypted, $out );&nbsp; &nbsp; &nbsp; &nbsp; /* for simplicity, cast as an object to use object notation */&nbsp; &nbsp; &nbsp; &nbsp; $obj=(object)$out;&nbsp; &nbsp; &nbsp; &nbsp; $endpoint=$obj->endpoint;&nbsp; &nbsp; &nbsp; &nbsp; $expires=$obj->expires;&nbsp; &nbsp; &nbsp; &nbsp; $ip=$obj->ip;&nbsp; &nbsp; &nbsp; &nbsp; /* perform logic tests on the decrypted data and act accordingly */&nbsp; &nbsp; &nbsp; &nbsp; if( time() > $expires or $ip!=$_SERVER['REMOTE_ADDR'] ){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* too late */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( '<h1>That link has now expired</h1><p>You are no longer premitted to access that resource</p>' );&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* all good */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( '<h1>Welcome</h1><p>%s</p>', $obj->endpoint );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

至尊宝的传说

我没有复制你代码的所有部分,但这是原则。将密码和时间分开散列,这样您就可以确保密码正确并独立查看时间。$secret = "PASSWORD";$expires = time()+3600;&nbsp;$urls= 'http://example.com?md5=" . md5($secret) . "&t=" . md5($expires);这将独立传递它们,在接收端您将密码与密码匹配,然后循环时间查看它是否有效。if($_GET['md5'] == $password) $validM = true;for($i = time()+3600; $i>time(); $i--){&nbsp; &nbsp; if(md5($i) == $_GET['t']) $validT = true;&nbsp;}if($validM && $validT){&nbsp; &nbsp; echo "within 3600 seconds and correct password";}对于世界上大约 95% 的人口来说,这是一种安全的方法,但由于我们通过 GET 传递密码和时间变量,因此弄清楚如何获得非法访问并不难。如果它需要安全事务,您正在使用它,则不要使用此方法。
随时随地看视频慕课网APP
我要回答