Судя по всему, правильнее вместо HMAC использовать шифрование любым стандартным алгоритмом использующим IV:
encrypt_aes_cbc($pepper, bcrypt($password))
Причин несколько:
- Возможность заменить $pepper в любой момент (периодически, или после утечки).
- Использовать MAC для этой цели это misuse - он предназначен для другой задачи, в отличие от шифрования, которое здесь как раз на своём месте.
- Последовательное хеширование разными алгоритмами без криптоанализа может ослабить безопасность; кроме того это изобретение собственного крипто-алгоритма, чего лучше избегать.
Но если есть такая возможность, то гораздо надёжнее не использовать шифрование и $pepper, а вместо этого запретить пользователям использовать слишком простые пароли (всё-таки если хакеры нашли SQLi, то часто они могут добраться и до чтения файлов, а значит узнать $pepper).
Что касается моего второго вопроса, то смутившая меня передача $pepper последним параметром была вызвана тем, что в примерах использовался синтаксис PHP, а там ключ передаётся последним.