Travis CI: PHP 7.2 don't support Argon2i

2020-07-30 05:08发布

问题:

I've an error in my project with Travis CI:

Argon2i algorithm is not supported. Please install the libsodium extension
or upgrade to PHP 7.2+.

But, Argon2i is present in the PHP 7.2 version and Travis CI install the PHP 7.2 version:

$ phpenv global 7.2 2>/dev/null

7.2 is not pre-installed; installing
Downloading archive: https://s3.amazonaws.com/travis-php-archives/binaries/ubuntu/14.04/x86_64/php-7.2.tar.bz2
$ curl -s -o archive.tar.bz2 $archive_url && tar xjf archive.tar.bz2 --directory /

$ phpenv global 7.2

$ php --version
PHP 7.2.0 (cli) (built: Dec  2 2017 17:12:55) ( ZTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.2.0, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.6.0-dev, Copyright (c) 2002-2017, by Derick Rethans

Someone have an idea ?

回答1:

I faced the same problem recently in a Symfony 4 project and posted an issue on Travis' Github.

However, the problem does not seem to come from Travis but from PHP 7.2 default build itself.

Quoting myself:

I was locally using a pre-configured PHP, so to be sure I just compiled PHP 7.2 from sources.

$ ./php -v
PHP 7.2.0 (cli) (built: Dec  6 2017 15:26:29) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies

Then I tryed to use the ARGON2I algorithm such as described in official docs:

$ ./php -r 'echo password_hash("test", PASSWORD_ARGON2I) . "\n";'
Warning: Use of undefined constant PASSWORD_ARGON2I - assumed 
'PASSWORD_ARGON2I' (this will throw an Error in a future version of PHP) in Command line code on line 1
Warning: password_hash() expects parameter 2 to be integer, string given in Command line code on line 1

While not having any problem with BCRYPT:

$ ./php -r 'echo password_hash("test", PASSWORD_BCRYPT) . "\n";'
$2y$10$wsWe3BhyzenVqDs6JV/fPOB0XKh0oTuGdrgLp61MnUPzOUdw4jZey

This is strange. I would have expected this algorithm to be part of the default PHP 7.2 build, just as other hash algorithms. And nothing seems to indicate the opposite in the docs. I'll investigate. Maybe I understood something wrong... but this looks like a bug to me, since they say here that PASSWORD_ARGON2I is part of PHP core.


Edit:

In the light of Sheppard's comment, it appears indeed that 7.2 does not implement the PASSWORD_AGRON2Ialgorithm in its default build. PHP has to be compiled with option -with-password-argon2, such as described in https://wiki.php.net/rfc/argon2_password_hash.



回答2:

It appear PHP 7.2 haven't argon2i password hasher by default, it's a compile option, but TravisCi don't use it in their PHP images, then we can avoid this error by adding a library (initially used in PHP < 7.2 versions) as mensionned in https://symfony.com/blog/new-in-symfony-3-4-argon2i-password-hasher, but not in our composer.json directly, call it in .travis.yml file:

before_install:
  # Fix Argon2i password hasher in TravisCi PHP version
  - composer require paragonie/sodium_compat

EDIT:

Because Symfony has been updated, the previous solution no longer works, then I choose to directly add the libsodium extension with PECL. This method is better I think, because we install and enable the PHP extension.

We must download sources of the libsodium library because ubuntu 14.04 haven't the library, then compile it, and compile the PHP extension with pecl, and enable it.

It works well, but it take more time than the previous solution.

before_install:
  # Manually compile the libsodium library
  - sudo apt-get update -qq
  - sudo apt-get install build-essential git -y
  - git clone -b stable https://github.com/jedisct1/libsodium.git
  - cd libsodium && sudo ./configure && sudo make check && sudo make install && cd ..
  - '[[ "$TRAVIS_PHP_VERSION" == "nightly" ]] || phpenv config-rm xdebug.ini'
  - composer self-update

install:
  # Manually install libsodium, because the TravicCi image doesn't provide PHP7.2 with libsodium
  - pecl install libsodium
  - echo "extension=sodium.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini


回答3:

This is indeed a silly dropped-ball by PHP. Fortunately there is a reasonable workaround - while libargon2 is not compiled in by default (because it's not available on all the platforms that PHP is), libsodium is, and though libsodium doesn't provide the PASSWORD_ARGON2I constant, it has the sodium_crypto_pwhash function, which uses the Argon2id variant of the Argon2 password hashing algorithm, which is stronger than the stock PHP 7.2 Argon2i, but is not compatible with it. You use it like this:

$hash = sodium_crypto_pwhash_str(
    $password, 
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

You can get this function in PHP versions prior to PHP 7.2 using the paragonie/sodium_compat library via composer.

I think transparent fallback through this was a missed opportunity in Symfony - it ends up failing to provide an implementation in exactly the same way that PHP itself does, which is no help to anyone.



标签: travis-ci