我使用PHP并需要设计激活器链接
$data = $user->email;
$key = $user->token; // bin2hex(openssl_random_pseud_bytes(16));
$hmac = hash_hmac( 'sha256', $data, $key );
因此,会向用户发送以下网址
hostname/account/confirm/7c7b0f24eff74902cb07e900b07a0cafc8fccfa5d2704fb92aaf3b91e9774f98
这种方式好主意?
如果为true,sha256
是hash_hmac()
在这种情况下的最佳选择?特别是,我希望有一个length <= 24
答案 0 :(得分:2)
TL; DR::此用例无需使用hash_hmac()
。您可以直接使用令牌。
如果$user->token
是安全生成的(由于collisions in OpenSSL's random number generator,您想要random_bytes()
而不是openssl_random_pseudo_bytes()
是nb),那么它是一个安全的随机值,攻击者无法无需破解表就知道它。
如果您想验证发送到用户电子邮件地址的一些明文数据,则可以使用HMAC。
例如:注册时,如果您需要为用户提供一个选项(例如GDPR同意),则可以创建以下两个URL绑定到同一令牌,就像这样:
$hmacYes = hash_hmac('sha256', 'yes', $user->token);
$hmacNo = hash_hmac('sha256', 'no', $user->token);
然后,每个选项可以有两个链接,并按以下方式发送链接:
* `hostname/account/confirm/yes${hmacYes}`
* `hostname/account/confirm/no${hmacNo}`
然后您可以解析出HMAC值:
if (!preg_match('/^(yes|no)(.*)$/', $urlParam, $matches) {
throw new SecurityException('bad url');
}
$choice = $matches[1];
$hmac = $matches[2];
$recalc = hash_hmac('sha256', $choice, $user->token);
if (!hash_equals($recalc, $mac)) {
throw new SecurityException('bad url');
}
// Now you know $choice is from a genuine user email
但是,如果仅需要质询响应身份验证,那么安全的随机令牌就足够了。