paragonie / ecc
PHP 椭圆曲线密码学库
Requires
- php: ^7.1||^8.0
- ext-gmp: *
- genkgo/php-asn1: ^2
- paragonie/sodium_compat: ^1|^2
Requires (Dev)
- ext-json: *
- phpunit/phpunit: ^6|^7|^8|^9
- squizlabs/php_codesniffer: ^2|^3
- symfony/yaml: ^2.6|^3.0|^4
- vimeo/psalm: ^2|^3|^4|^5
Suggests
- ext-openssl: (PHP 8.1, OpenSSL 3+) Improved performance, less worries about side-channels
This package is auto-updated.
Last update: 2024-08-31 00:41:48 UTC
README
注意
这个库是从 phpecc/phpecc
分支出来的,而 phpecc/phpecc
又是 mdanter/ecc
的分支。它应该可以作为任何以前依赖于这两种方法的应用的直接替代。
安全信息
默认情况下,这个库将首先尝试使用 OpenSSL 的实现。这需要 PHP 8.1+ 和 OpenSSL 3.0+ 才能工作。OpenSSL 的实现应该是恒定时间的。
当 OpenSSL 不可用时,这个库将回退到纯 PHP 实现。实际上有两种实现:
- 每个椭圆曲线的优化恒定时间实现。
- 与原始 PHP ECC 库一起提供的通用椭圆曲线算法。
我们已经尽最大努力加固了我们对这个库的分支,以抵御“优化”代码中的侧信道攻击。
我们无法保证通用椭圆曲线代码是恒定时间的。我们敦促用户使用 OpenSSL 的实现或我们的恒定时间实现。
此库实现了低级椭圆曲线密码学
如果您只需要 Diffie-Hellman 或 ECDSA,您应该安装 EasyECC 而不是直接与此库合作。EasyECC 是设计用来以安全的方式使用 PHPECC 的。
历史信息
这个库是 Matyas Danter 的 ECC 库的重新编写/更新。所有荣誉都归他所有。
库支持以下曲线
- secp256k1
- nistp256 / secp256r1
- nistp384 / secp384r1
- nistp521
- brainpoolp256r1
- brainpoolp384r1
- brainpoolp512r1
此外,如果启用了不安全的曲线,还将提供以下曲线:
- secp112r1
- nistp192
- nistp224
在 ECDSA 中,需要一个随机的值 k
。使用真正的 RNG 生成此值是可以接受的,但如果相同的 k
值被反复用于密钥,攻击者可以恢复该签名密钥。
然而,实际上比简单的“重用”问题更糟糕。即使您从未重用 k
值,如果您在 k
的位分布中有任何偏差,观察足够签名的攻击者可以使用格降低来恢复您的密钥。
HMAC 随机生成器可以从消息哈希和私钥中派生出确定的 k 值。这提供了无偏的位分布,因此适合解决此问题。
库使用非分支蒙哥马利梯形进行标量乘法,因为它恒定时间且避免了秘密相关的分支。
“优化”的恒定时间代码使用 素数阶椭圆曲线的完整加法公式 来避免点加法和点双倍中的侧信道。
许可证
此软件包根据 MIT 许可证发布。
要求
- PHP 7.1+ 或 PHP 8.0+
- composer
- ext-gmp
安装
您可以通过 Composer 安装此库
composer require paragonie/ecc:^2
贡献
在发送拉取请求时,请确保运行 make
命令。
默认目标运行所有 PHPUnit 和 PHPCS 测试。所有测试都必须验证您的贡献才能被接受。
检查您拉取请求的 Scrutinizer 分析结果 总是一个好主意。
用法
示例
不安全曲线
EccFactory
类默认只允许您实例化安全的椭圆曲线。以下任一条件成立,则椭圆曲线被认为是安全的:
- 如果我们能依赖 OpenSSL 提供其实现,则认为是安全的。
- 如果我们有一个优化的常量时间实现,则认为是安全的。
- 如果曲线的椭圆曲线离散对数问题(ECDLP)的安全级别等于或低于 120 位,则认为是不安全的。(我们不会为这些曲线提供常量时间实现,因此第二步应该已经排除了这些曲线。)
- 否则,认为是不安全的。EccFactory 默认不允许这些曲线。
要绕过此防护措施,只需将 true
传递给第二个参数,如下所示
<?php use Mdanter\Ecc\EccFactory; use Mdanter\Ecc\Math\GmpMath; $adapter = new GmpMath(); // This will throw an InsecureCurveException: // $p192 = EccFactory::getNistCurves($adapter)->generator192(); // This will succeed: $p192 = EccFactory::getNistCurves($adapter, true)->generator192(); // This will also succeed, without any special considerations: $p256 = EccFactory::getNistCurves()->generator256();