PHP 椭圆曲线密码学库

v2.3.0 2024-05-01 14:04 UTC

This package is auto-updated.

Last update: 2024-08-31 00:41:48 UTC


README

Build Status Type Safety

Scrutinizer Code Quality Code Coverage

Latest Stable Version Total Downloads Latest Unstable Version License

注意

这个库是从 phpecc/phpecc 分支出来的,而 phpecc/phpecc 又是 mdanter/ecc 的分支。它应该可以作为任何以前依赖于这两种方法的应用的直接替代。

安全信息

默认情况下,这个库将首先尝试使用 OpenSSL 的实现。这需要 PHP 8.1+ 和 OpenSSL 3.0+ 才能工作。OpenSSL 的实现应该是恒定时间的。

当 OpenSSL 不可用时,这个库将回退到纯 PHP 实现。实际上有两种实现:

  1. 每个椭圆曲线的优化恒定时间实现。
  2. 与原始 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 类默认只允许您实例化安全的椭圆曲线。以下任一条件成立,则椭圆曲线被认为是安全的:

  1. 如果我们能依赖 OpenSSL 提供其实现,则认为是安全的。
  2. 如果我们有一个优化的常量时间实现,则认为是安全的。
  3. 如果曲线的椭圆曲线离散对数问题(ECDLP)的安全级别等于或低于 120 位,则认为是不安全的。(我们不会为这些曲线提供常量时间实现,因此第二步应该已经排除了这些曲线。)
  4. 否则,认为是不安全的。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();