In PHP, when we need to compare whether two strings are equal, the commonly used method is the strcmp function. However, with the increase in security requirements, PHP 5.6 introduced a function hash_equals specifically for security comparison. This article will introduce the differences between these two functions in detail and explain why hash_equals is recommended in some scenarios.
strcmp(string $str1, string $str2): int
strcmp is used to compare two strings in dictionary order. It returns an integer value:
0 means that the two strings are exactly the same
Negative numbers indicate that the first string is smaller than the second string
Positive number means that the first string is greater than the second string
hash_equals(string $known_string, string $user_string): bool
hash_equals is specifically used to compare whether two strings are exactly the same, and the comparison process is a safe way to prevent Timing Attacks. It returns a boolean value:
true means that two strings are exactly equal
false means unequal
In some security scenarios, such as verifying sensitive data such as password hash, API key, signature, etc., an attacker may infer the length of the same part of the string by measuring the execution time of the comparison function, and then gradually guess the correct key. Ordinary string comparison functions (such as strcmp ) will return immediately when the first different character is found, resulting in the comparison time being related to the part length of the string, which is prone to leak information.
Hash_equals is designed with special consideration to prevent timing attacks. The comparison time does not change with the length of the same part of the two strings, but instead fixes the execution time, thereby reducing the risk of leaking information.
<?php
// use strcmp Comparison of two strings
$known = 'securetoken123';
$userInput = 'securetoken124';
if (strcmp($known, $userInput) === 0) {
echo "Match successfully(strcmp)";
} else {
echo "Match failed(strcmp)";
}
?>
<?php
// use hash_equals Comparison of two strings
$known = 'securetoken123';
$userInput = 'securetoken124';
if (hash_equals($known, $userInput)) {
echo "Match successfully(hash_equals)";
} else {
echo "Match failed(hash_equals)";
}
?>
Note that in the string comparison in the above code, strcmp will return immediately on the first different character, and hash_equals will perform the full comparison.
Verify password hash : Although most password verifications pass password_verify , it is recommended to use hash_equals if you implement comparison hash by yourself.
Compare encrypted signatures : for example HMAC, JWT, etc. to avoid guessing the key.
Comparative security tokens : API keys, access tokens, verification codes, etc.
Simply put, it is recommended to use hash_equals for any security-related string comparison.
hash_equals requires that the two parameters passed in are strings and have the same length, otherwise false will be directly returned.
Before using hash_equals , it is recommended to ensure that the input strings are of string type and have the same length to avoid unexpected errors.
Although strcmp is a commonly used and powerful string comparison function, in safe and sensitive occasions, hash_equals is a more suitable choice because of its characteristic of preventing timed attacks. Correct use of hash_equals can effectively improve the security of the application and avoid potential attack risks.