1--TEST-- 2Test interoperability of password_verify() 3--SKIPIF-- 4<?php 5if (!function_exists('sodium_crypto_pwhash_str')) { 6 echo "skip - No crypto_pwhash_str_verify"; 7} 8 9// Depending on library version, libsodium may provide argon2i or argon2id hashes. 10$hash = sodium_crypto_pwhash_str("test", SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE); 11list(, $algo) = explode('$', $hash, 3); 12 13if (!in_array($algo, password_algos(), true /* strict */)) { 14 echo "skip - No $algo support in password_verify()"; 15} 16--FILE-- 17<?php 18 19$opsSet = [ 20 SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, 21 SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE, 22 SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE, 23]; 24$memSet = [ 25 SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE, 26 SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE, 27 SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE, 28]; 29 30echo 'Argon2 provider: '; 31var_dump(PASSWORD_ARGON2_PROVIDER); 32 33foreach($opsSet as $ops) { 34 foreach($memSet as $mem) { 35 $password = random_bytes(32); 36 echo "Using password: "; 37 var_dump(base64_encode($password)); 38 $hash = sodium_crypto_pwhash_str($password, $ops, $mem); 39 echo "Hash: "; var_dump($hash); 40 var_dump(password_verify($password, $hash)); 41 42 // And verify that incorrect passwords fail. 43 $password[0] = chr(ord($password[0]) ^ 1); 44 var_dump(password_verify($password, $hash)); 45 } 46} 47--EXPECTF-- 48Argon2 provider: string(%d) "%s" 49Using password: string(44) "%s" 50Hash: string(97) "$argon2id$v=19$m=65536,t=2,p=1$%s$%s" 51bool(true) 52bool(false) 53Using password: string(44) "%s" 54Hash: string(98) "$argon2id$v=19$m=262144,t=2,p=1$%s$%s" 55bool(true) 56bool(false) 57Using password: string(44) "%s" 58Hash: string(99) "$argon2id$v=19$m=1048576,t=2,p=1$%s$%s" 59bool(true) 60bool(false) 61Using password: string(44) "%s" 62Hash: string(97) "$argon2id$v=19$m=65536,t=3,p=1$%s$%s" 63bool(true) 64bool(false) 65Using password: string(44) "%s" 66Hash: string(98) "$argon2id$v=19$m=262144,t=3,p=1$%s$%s" 67bool(true) 68bool(false) 69Using password: string(44) "%s" 70Hash: string(99) "$argon2id$v=19$m=1048576,t=3,p=1$%s$%s" 71bool(true) 72bool(false) 73Using password: string(44) "%s" 74Hash: string(97) "$argon2id$v=19$m=65536,t=4,p=1$%s$%s" 75bool(true) 76bool(false) 77Using password: string(44) "%s" 78Hash: string(98) "$argon2id$v=19$m=262144,t=4,p=1$%s$%s" 79bool(true) 80bool(false) 81Using password: string(44) "%s" 82Hash: string(99) "$argon2id$v=19$m=1048576,t=4,p=1$%s$%s" 83bool(true) 84bool(false) 85