bitpay / php-bitpay-client

PHP implementation for the BitPay cryptographically secure RESTful API
MIT License
165 stars 148 forks source link

The input must be a numeric string in decimal or hexadecimal (with leading 0x) format #226

Closed gjuric closed 7 years ago

gjuric commented 7 years ago

Hi,

we updated the library from v2.2.11 to v2.2.13 and it broke our URL generation with the error from the subject.

It looks like it can not load the private key in the correct format. This is the stack trace:

#1 [internal function]: Bitpay\Math\BcEngine->cmp('0xrandom-string...', 0)
#2 vendor/bitpay/php-client/src/Bitpay/Math/Math.php(48): call_user_func_array(Array, Array)
#3 vendor/bitpay/php-client/src/Bitpay/Util/Util.php(406): Bitpay\Math\Math::__callStatic('cmp', Array)
#4 vendor/bitpay/php-client/src/Bitpay/Util/Util.php(406): Bitpay\Math\Math::cmp('0xrandom-string...', 0)
#5 vendor/bitpay/php-client/src/Bitpay/Storage/EncryptedFilesystemStorage.php(81): Bitpay\Util\Util::binConv('random-string...')
#6 [internal function]: Bitpay\Storage\EncryptedFilesystemStorage->load('/srv/www/...')
#7 var/cache/prod/appProdProjectContainer.php(2373): call_user_func(Array, '/srv/www/...')

I have anonymized the content of the private key ("random-string" is the actual private key on our server). It looks like a base64 encoded string and as far as I can tell in https://github.com/bitpay/php-bitpay-client/blob/v2.2.13/src/Bitpay/Math/BcEngine.php#L175 you expect a hex string.

gjuric commented 7 years ago

On further investigation I realised that when we first installed v2.2.11 (a year ago) the commit hash was different for this version. From the original composer.lock:

            "name": "bitpay/php-client",
            "version": "v2.2.11",
            "source": {
                "type": "git",
                "url": "https://github.com/bitpay/php-bitpay-client.git",
                "reference": "66537e588f7af42858f2d378feb70413ab4e55cd"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/bitpay/php-bitpay-client/zipball/66537e588f7af42858f2d378feb70413ab4e55cd",
                "reference": "66537e588f7af42858f2d378feb70413ab4e55cd",
                "shasum": ""
            },
            "require": {
                "ext-bcmath": "*",
                "ext-curl": "*",
                "ext-json": "*",
                "ext-mcrypt": "*",
                "ext-openssl": "*",
                "php": ">=5.4",
                "symfony/config": "^2.3 || ^3.0",
                "symfony/dependency-injection": "^2.3 || ^3.0"
            },
            "require-dev": {
                "behat/behat": "master-dev",
                "behat/mink": "master-dev",
                "behat/mink-extension": "master-dev",
                "behat/mink-goutte-driver": "1.*",
                "behat/mink-selenium2-driver": "1.2.0",
                "fabpot/goutte": "~1.0.4",
                "fzaninotto/faker": "~1.4.0",
                "mikey179/vfsstream": "~1.4.0",
                "phpmd/phpmd": "master-dev",
                "phpunit/phpunit": "~4.3.1",
                "satooshi/php-coveralls": "~0.6.1",
                "squizlabs/php_codesniffer": "~1.5.5"
            },
            "suggest": {
                "ext-gmp": "Quickest PHP math extension for doing computationally-expensive work."
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "2.2.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "BitPay Integrations Development Team",
                    "email": "integrations@bitpay.com",
                    "homepage": "https://bitpay.com/integrations"
                }
            ],
            "description": "PHP Library to work with the cryptographically secure BitPay API",
            "homepage": "https://github.com/bitpay/php-bitpay-client",
            "keywords": [
                "bitcoin",
                "bitpay"
            ],
            "time": "2016-02-16 15:43:30"
        }, 

when you install v2.2.11 now, you get:

            "name": "bitpay/php-client",
            "version": "v2.2.11",
            "source": {
                "type": "git",
                "url": "https://github.com/bitpay/php-bitpay-client.git",
                "reference": "3235c32054e552c565e881cacf9a70b301a5a2cc"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/bitpay/php-bitpay-client/zipball/3235c32054e552c565e881cacf9a70b301a5a2cc",
                "reference": "3235c32054e552c565e881cacf9a70b301a5a2cc",
                "shasum": ""
            },
            "require": {
                "ext-bcmath": "*",
                "ext-curl": "*",
                "ext-json": "*",
                "ext-mcrypt": "*",
                "ext-openssl": "*",
                "php": ">=5.4",
                "symfony/config": "^2.3 || ^3.0",
                "symfony/dependency-injection": "^2.3 || ^3.0"
            },
            "require-dev": {
                "behat/behat": "2.5.*@stable",
                "behat/mink": "1.6.1",
                "behat/mink-extension": "1.3.*",
                "behat/mink-goutte-driver": "1.*",
                "behat/mink-selenium2-driver": "1.2.0",
                "fabpot/goutte": "~1.0.4",
                "fzaninotto/faker": "~1.4.0",
                "mikey179/vfsstream": "~1.4.0",
                "phpmd/phpmd": "~2.1.3",
                "phpunit/phpunit": "~4.3.1",
                "satooshi/php-coveralls": "~0.6.1",
                "squizlabs/php_codesniffer": "~1.5.5"
            },
            "suggest": {
                "ext-gmp": "Quickest PHP math extension for doing computationally-expensive work."
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "2.2.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "BitPay Integrations Development Team",
                    "email": "integrations@bitpay.com",
                    "homepage": "https://bitpay.com/integrations"
                }
            ],
            "description": "PHP Library to work with the new cryptographically secure BitPay API",
            "homepage": "https://github.com/bitpay/php-bitpay-client",
            "keywords": [
                "bitcoin",
                "bitpay"
            ],
            "time": "2017-05-09T10:28:02+00:00"
        },

It looks like you overwrote the v2.2.11 tag by accident and made it point to commit https://github.com/bitpay/php-bitpay-client/commit/3235c32054e552c565e881cacf9a70b301a5a2cc instead of https://github.com/bitpay/php-bitpay-client/commit/66537e588f7af42858f2d378feb70413ab4e55cd

The difference between these two commits is that the new one generates the private/public keypar sorted as a hex string, while the original version does not.

gjuric commented 7 years ago

If you look at this fork: https://github.com/marcod85/php-bitpay-client/releases you can see tags for versions 2.2.9 (January 2016) and 2.2.10 (February 2016) and if you take a look at your current tags on https://github.com/bitpay/php-bitpay-client/tags it looks like version 2.2.9 was tagged in February of this year, not 2016 and you are missing a tag for 2.2.10 so I am pretty sure something is broken here.

sbacelic commented 7 years ago

v2.2.11 was definitely overwritten, it is an old tag (from 2016-02-16, check here 4f370def472878b591afb686c69ed5cca223920d) while current v2.2.11 is tagged 10 days ago. This broke my installation as well. Current 2.2.11 introduced breaking change where the private key is expected in hex format while previously it was encoded in base64.

pieterpoorthuis commented 7 years ago

It looks like the older libs (<v2.2.11) store keys in a different format. I'll check how both formats (hex & base64) can be supported

gjuric commented 7 years ago

Please check what happened with the tags as well. v2.2.11 that we had in production for a while was working with base64 keys, but the currently tagged 2.2.11 is not the same version that we were running and this version does not work with base64 keys.

pieterpoorthuis commented 7 years ago

I'm trying to reproduce the error by creating a private/public key using v2.2.8 and loading it with v2.2.13, but it just works for me.

Can you explain in more detail how you stored your private/public keys, and how you are loading them?

gjuric commented 7 years ago

The keys were created a year ago with v2.2.10 which is not available anymore, the code that created them looked like this:

$privateKey = PrivateKey::create($privateKeyPath)->generate();
$publicKey = PublicKey::create($publicKeyPath)->setPrivateKey($privateKey)->generate();

and the keys were stored using the EncryptedFilesystemStorage.

In the end we upgraded to v2.2.13 and issued a new set of keys (with the current instructions) to fix the problem.

BTW; what is the recommended version to use? Running composer require without parameters installs v3, but in your README you say that we should use ^2.2

pieterpoorthuis commented 7 years ago

The recommended version to use is v2.