我正在比较在不同的域上用相同的值(IP、时间、路径和密码)创建的两个base64_encode md5键。
在第一个域上创建加密密钥
$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>';
}我在加密中使用了时间( 3600 ),所以if语句应该是3600秒的显示值。但这总是显示else值。
如何打印if 值的时间(3600)?之后,打印
发布于 2019-08-11 07:38:19
我还没有复制您代码的所有部分,但这是原则。
散列密码和时间分开,这样您就可以确保密码是正确的,并独立查看时间。
$secret = "PASSWORD";
$expires = time()+3600;
$urls= 'http://example.com?md5=" . md5($secret) . "&t=" . md5($expires);这将独立地传递它们,在接收端,您将密码与密码匹配,并循环时间来查看它是否有效。
if($_GET['md5'] == $password) $validM = true;
for($i = time()+3600; $i>time(); $i--){
if(md5($i) == $_GET['t']) $validT = true;
}
if($validM && $validT){
echo "within 3600 seconds and correct password";
}对于世界上95%的人口来说,这是一种安全的方法,但由于我们通过GET传递密码和时间变量,所以不难找到如何获得非法访问。
--如果它需要安全的事务,那么就不要使用这个方法.
发布于 2019-08-11 08:02:37
也许超出了问题的范围,但是整个MD5方法是有缺陷的,所以为什么不像在问题中那样使用加密而不是散列呢?
encrypt和decrypt函数基于加密手册中的代码
function encrypt( $data=false, $pubkey=false, $cipher='AES-128-CBC' ){
if( !empty( $data ) && in_array( $cipher, openssl_get_cipher_methods() ) ){
$ivlen = openssl_cipher_iv_length( $cipher );
$iv = openssl_random_pseudo_bytes( $ivlen );
$encrypted = openssl_encrypt( $data, $cipher, $pubkey, $options=OPENSSL_RAW_DATA, $iv );
$hash = makehash( $encrypted, $pubkey );
return base64_encode( $iv . $hash . $encrypted );
}
return false;
}
function decrypt( $data, $pubkey=false, $cipher='AES-128-CBC' ){
if( !empty( $data ) && in_array( $cipher, openssl_get_cipher_methods() ) ){
$shalength=32;
$data = base64_decode( $data );
$ivlen = openssl_cipher_iv_length( $cipher );
$iv = substr( $data, 0, $ivlen );
$hash = substr( $data, $ivlen, $shalength );
$encrypted = substr( $data, $ivlen + $shalength );
$decrypted = openssl_decrypt( $encrypted, $cipher, $pubkey, $options=OPENSSL_RAW_DATA, $iv );
if( $decrypted && hash_equals( $hash, makehash( $encrypted, $pubkey ) ) ){
return $decrypted;
}
}
return false;
}
function makehash( $data, $key ){
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(
'endpoint' => '/secret-forum/topic404',
'expires' => time() + $lifetime,
'ip' => $_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 ) ){
list( $param, $data )=explode( '=', $querystring );
/* decrypt data */
$decrypted=decrypt( $data, $key, $cipher );
if( $decrypted ){
/* process initial querystring we created - create an array $out */
parse_str( $decrypted, $out );
/* for simplicity, cast as an object to use object notation */
$obj=(object)$out;
$endpoint=$obj->endpoint;
$expires=$obj->expires;
$ip=$obj->ip;
/* perform logic tests on the decrypted data and act accordingly */
if( time() > $expires or $ip!=$_SERVER['REMOTE_ADDR'] ){
/* too late */
printf( '<h1>That link has now expired</h1><p>You are no longer premitted to access that resource</p>' );
} else {
/* all good */
printf( '<h1>Welcome</h1><p>%s</p>', $obj->endpoint );
}
}
}https://stackoverflow.com/questions/57448005
复制相似问题