定制 starkbank/ecdsa 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

starkbank/ecdsa

Composer 安装命令:

composer require starkbank/ecdsa

包简介

fast openSSL-compatible implementation of the Elliptic Curve Digital Signature Algorithm (ECDSA)

README 文档

README

Overview

This is a pure PHP implementation of the Elliptic Curve Digital Signature Algorithm. It is compatible with OpenSSL and uses elegant math such as Jacobian Coordinates to speed up the ECDSA on pure PHP.

Security

starkbank-ecdsa includes the following security features:

  • RFC 6979 deterministic nonces: Eliminates the catastrophic risk of nonce reuse that leaks private keys
  • Low-S signature normalization: Prevents signature malleability (BIP-62)
  • Public key on-curve validation: Blocks invalid-curve attacks during verification
  • Montgomery ladder scalar multiplication: Constant-operation point multiplication to mitigate timing side channels
  • Hash truncation: Correctly handles hash functions larger than the curve order (e.g. SHA-512 with secp256k1)

Installation

Composer

To install the package with Composer, run:

composer require starkbank/ecdsa

To use the bindings, use Composer's autoload:

require_once('vendor/autoload.php');

External dependencies

The package makes use of the 'GNU Multiple Precision' (GMP) library. For installation details, see: https://www.php.net/manual/en/gmp.installation.php

Curves

We currently support secp256k1 and prime256v1 (P-256), but you can add more curves to the project. You just need to use the CurveFp::add() method.

Speed

We ran a test on a MAC Pro using PHP 8.5. The library was run 100 times and the averages displayed below were obtained:

Library sign verify
starkbank-ecdsa 0.3ms 0.8ms

Performance is driven by Jacobian coordinates, a branch-balanced Montgomery ladder for variable-base scalar multiplication, a precomputed affine table of powers-of-two multiples of the generator ([G, 2G, 4G, ..., 2^n*G]) combined with a width-2 NAF of the scalar to eliminate doublings during signing, a mixed affine+Jacobian addition fast path, curve-specific shortcuts in point doubling (A=0 for secp256k1, A=-3 for prime256v1), the secp256k1 GLV endomorphism to split 256-bit scalars into two ~128-bit halves for a 4-scalar simultaneous multi-exponentiation during verification, Shamir's trick with Joint Sparse Form as the fallback path for curves without an efficient endomorphism, and the extended Euclidean algorithm for modular inversion.

Sample Code

How to sign a json message for Stark Bank:

# 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);

Simple use:

# 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);

How to add more curves:

$newCurve = new EllipticCurve\CurveFp(
    "0xf1fd178c0b3ad58f10126de8ce42435b3961adbcabc8ca6de8fcf353d86e9c00",
    "0xee353fca5428a9300d4aba754a44c00fdfec0c9ae4b1a1803075ed967b7bb73f",
    "0xf1fd178c0b3ad58f10126de8ce42435b3961adbcabc8ca6de8fcf353d86e9c03",
    "0xf1fd178c0b3ad58f10126de8ce42435b53dc67e140d2bf941ffdd459c6d655e1",
    "0xb6b3d4c356c139eb31183d4749d423958c27d2dcaf98b70164c97a2dd98f5cff",
    "0x6142e0f7c8b204911f9271f0f3ecef8c2701c307e8e4c9e183115a1554062cfb",
    "frp256v1",
    array(1, 2, 250, 1, 223, 101, 256, 1)
);

EllipticCurve\CurveFp::add($newCurve);

$publicKeyPem = "-----BEGIN PUBLIC KEY-----
MFswFQYHKoZIzj0CAQYKKoF6AYFfZYIAAQNCAATeEFFYiQL+HmDYTf+QDmvQmWGD
dRJPqLj11do8okvkSxq2lwB6Ct4aITMlCyg3f1msafc/ROSN/Vgj69bDhZK6
-----END PUBLIC KEY-----";

$publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem);

print_r($publicKey->toPem());

How to generate a compressed public key:

$privateKey = new EllipticCurve\PrivateKey;
$publicKey = $privateKey->publicKey();
$compressedPublicKey = $publicKey->toCompressed();

echo $compressedPublicKey;

How to recover a compressed public key:

$compressedPublicKey = "0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2";
$publicKey = EllipticCurve\PublicKey::fromCompressed($compressedPublicKey);

print_r($publicKey->toPem());

OpenSSL

This library is compatible with OpenSSL, so you can use it to generate keys:

openssl ecparam -name secp256k1 -genkey -out privateKey.pem
openssl ec -in privateKey.pem -pubout -out publicKey.pem

Create a message.txt file and sign it:

openssl dgst -sha256 -sign privateKey.pem -out signatureDer.txt message.txt

It's time to verify:

$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);

You can also verify it on terminal:

openssl dgst -sha256 -verify publicKey.pem -signature signatureDer.txt message.txt

NOTE: If you want to create a Digital Signature to use in the Stark Bank, you need to convert the binary signature to base64.

openssl base64 -in signatureDer.txt -out signatureBase64.txt

You can also verify it with this library:

$signatureDer = EllipticCurve\Utils\File::read("signatureDer.txt");

$signature = EllipticCurve\Signature::fromDer($signatureDer);

echo "\n" . $signature->toBase64();

Run all unit tests

php tests/test.php

Run benchmark

php benchmark.php

starkbank/ecdsa 适用场景与选型建议

starkbank/ecdsa 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 38.04M 次下载、GitHub Stars 达 114, 最近一次更新时间为 2020 年 01 月 07 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 starkbank/ecdsa 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 starkbank/ecdsa 我们能提供哪些服务?
定制开发 / 二次开发

基于 starkbank/ecdsa 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 38.04M
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 115
  • 点击次数: 42
  • 依赖项目数: 20
  • 推荐数: 0

GitHub 信息

  • Stars: 114
  • Watchers: 4
  • Forks: 17
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-01-07