starkbank / ecdsa
快速的开SSL兼容的椭圆曲线数字签名算法(ECDSA)实现
2.1.0
2023-09-06 22:09 UTC
Requires
- php: >=7.0
- ext-gmp: *
This package is not auto-updated.
Last update: 2024-09-19 02:49:02 UTC
README
概览
这是椭圆曲线数字签名算法(ECDSA)的纯PHP实现。它与OpenSSL兼容,并使用雅可比坐标等优雅的数学方法来加速纯PHP中的ECDSA。
安装
Composer
使用Composer安装包,运行
composer require starkbank/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次库,并在下面显示平均时间
示例代码
如何为Stark Bank签名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 Stark Bank 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
注意:如果您想创建用于Stark Bank的数字签名,则需要将二进制签名转换为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