fabank / ecdsa
快速、兼容 OpenSSL 的椭圆曲线数字签名算法 (ECDSA) 实现
1.0.0
2023-10-23 19:00 UTC
Requires
- php: >=7.0
- ext-gmp: *
This package is not auto-updated.
Last update: 2024-09-24 22:06:29 UTC
README
概述
这是椭圆曲线数字签名算法的纯 PHP 实现。它与 OpenSSL 兼容,并使用雅可比坐标等优雅的数学方法来加速纯 PHP 中的 ECDSA。
安装
Composer
要使用 Composer 安装此包,请运行
composer require fabank/ecdsa
要使用绑定,请使用 Composer 的自动加载
require_once('vendor/autoload.php');
外部依赖
此包使用 'GNU 多精度' (GMP) 库。有关安装详细信息,请参阅: https://php.ac.cn/manual/en/gmp.installation.php
曲线
我们目前支持 secp256k1
,但您可以在项目中添加更多曲线。您只需要使用 Curve::add()
方法。
速度
我们在 2020 款 Macbook Air M1 上使用 PHP 8.1 进行了测试。我们运行了 100 次库,并显示了下面的平均时间。
示例代码
如何为 Fabank 签名 JSON 消息
# Generate privateKey from PEM string $privateKey = EllipticCurve\PrivateKey::fromPem(" -----BEGIN EC PARAMETERS----- BgUrgQQACg== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- MHQCAQEEIODvZuS34wFbt0X53+P5EnSj6tMjfVK01dD1dgDH02RzoAcGBSuBBAAK oUQDQgAE/nvHu/SQQaos9TUljQsUuKI15Zr5SabPrbwtbfT/408rkVVzq8vAisbB RmpeRREXj5aog/Mq8RrdYy75W9q/Ig== -----END EC PRIVATE KEY----- "); # Create message from json $message = array( "transfers" => array( array( "amount" => 100000000, "taxId" => "594.739.480-42", "name" => "Daenerys Targaryen Stormborn", "bankCode" => "341", "branchCode" => "2201", "accountNumber" => "76543-8", "tags" => array("daenerys", "targaryen", "transfer-1-external-id") ) ) ); $message = json_encode($message, JSON_PRETTY_PRINT); $signature = EllipticCurve\Ecdsa::sign($message, $privateKey); # Generate Signature in base64. This result can be sent to Fabank in header as Digital-Signature parameter echo "\n" . $signature->toBase64(); # To double check if message matches the signature $publicKey = $privateKey->publicKey(); echo "\n" . EllipticCurve\Ecdsa::verify($message, $signature, $publicKey);
简单使用
# Generate new Keys $privateKey = new EllipticCurve\PrivateKey; $publicKey = $privateKey->publicKey(); $message = "My test message"; # Generate Signature $signature = EllipticCurve\Ecdsa::sign($message, $privateKey); # Verify if signature is valid echo "\n" . EllipticCurve\Ecdsa::verify($message, $signature, $publicKey);
如何添加更多曲线
$newCurve = new EllipticCurve\Curve( "0xf1fd178c0b3ad58f10126de8ce42435b3961adbcabc8ca6de8fcf353d86e9c00", "0xee353fca5428a9300d4aba754a44c00fdfec0c9ae4b1a1803075ed967b7bb73f", "0xf1fd178c0b3ad58f10126de8ce42435b3961adbcabc8ca6de8fcf353d86e9c03", "0xf1fd178c0b3ad58f10126de8ce42435b53dc67e140d2bf941ffdd459c6d655e1", "0xb6b3d4c356c139eb31183d4749d423958c27d2dcaf98b70164c97a2dd98f5cff", "0x6142e0f7c8b204911f9271f0f3ecef8c2701c307e8e4c9e183115a1554062cfb", "frp256v1", array(1, 2, 250, 1, 223, 101, 256, 1) ); EllipticCurve\Curve::add($newCurve); $publicKeyPem = "-----BEGIN PUBLIC KEY----- MFswFQYHKoZIzj0CAQYKKoF6AYFfZYIAAQNCAATeEFFYiQL+HmDYTf+QDmvQmWGD dRJPqLj11do8okvkSxq2lwB6Ct4aITMlCyg3f1msafc/ROSN/Vgj69bDhZK6 -----END PUBLIC KEY-----"; $publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem); print_r($publicKey->toPem());
OpenSSL
此库与 OpenSSL 兼容,因此您可以使用它来生成密钥
openssl ecparam -name secp256k1 -genkey -out privateKey.pem
openssl ec -in privateKey.pem -pubout -out publicKey.pem
创建一个 message.txt 文件并对其进行签名
openssl dgst -sha256 -sign privateKey.pem -out signatureDer.txt message.txt
现在是验证时间
$publicKeyPem = EllipticCurve\Utils\File::read("publicKey.pem"); $signatureDer = EllipticCurve\Utils\File::read("signatureDer.txt"); $message = EllipticCurve\Utils\File::read("message.txt"); $publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem); $signature = EllipticCurve\Signature::fromDer($signatureDer); echo "\n" . EllipticCurve\Ecdsa::verify($message, $signature, $publicKey);
您也可以在终端中对其进行验证
openssl dgst -sha256 -verify publicKey.pem -signature signatureDer.txt message.txt
注意:如果您想为 Fabank 创建用于使用的数字签名,您需要将二进制签名转换为 base64。
openssl base64 -in signatureDer.txt -out signatureBase64.txt
您也可以使用此库进行验证
$signatureDer = EllipticCurve\Utils\File::read("signatureDer.txt"); $signature = EllipticCurve\Signature::fromDer($signatureDer); echo "\n" . $signature->toBase64();
运行所有单元测试
php tests/test.php