PHP椭圆曲线密码学库

v0.3.2 2014-07-07 12:44 UTC

This package is auto-updated.

Last update: 2024-09-24 09:00:59 UTC


README

Build Status HHVM Status

Scrutinizer Code Quality Code Coverage

Latest Stable Version Total Downloads Latest Unstable Version License

信息

这个库是对Matyas Danter的ECC库的重写/更新。所有的赞誉都归功于他。

关于椭圆曲线密码学的更多信息,请阅读这篇优秀的文章

许可证

此软件包在MIT许可证下发布。

要求

  • PHP 5.4+
  • composer
  • ext-gmp
  • ext-mcrypt

安装

您可以通过Composer安装此库

composer require mdanter/ecc

贡献

在提交拉取请求时,请确保运行make命令。

默认目标运行所有PHPUnit和PHPCS测试。所有测试都必须通过,您的贡献才能被接受。

检查您的拉取请求的Scrutinizer分析结果也是一个好主意。

用法

警告 尽管这个库已经过测试,符合标准,但至少有一个已记录的公开密钥派生漏洞,这可能允许攻击者获取您的私钥。 请自行承担风险。 已提醒。

警告 以下所有文档基于master分支,而不是标记版本。

密钥生成

懒方法

您很幸运,有一个命令行工具!以下示例假设phpecc(位于bin/目录中)已添加到您的路径。

生成一个私钥/公钥对

$ phpecc genkey --curve=nist-p256 --out=pem
Using curve "nist-p256"
-----BEGIN EC PRIVATE KEY-----
MHYCAQEEHxMDwxsmFiNDNtNXZIfDm7xYlwJU3YedMA3zyhz/0+OgCgYIKoZIzj0D
AQehRANCAATHZZfy/pz9cqrVldcbtM2ucDYahx8IZZWY8/txTGfmwE9VhZDxh2w6
rJruv+3BMOmKqI42MvpuE02U+Rhlf9ch
-----END EC PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEx2WX8v6c/XKq1ZXXG7TNrnA2Gocf
CGWVmPP7cUxn5sBPVYWQ8YdsOqya7r/twTDpiqiONjL6bhNNlPkYZX/XIQ==
-----END PUBLIC KEY-----

或者,您可以将输出重定向到文件

$ phpecc genkey --curve=nist-p256 --out=pem > keypair.pem
Using curve "nist-p256"

生成的密钥应该与OpenSSL兼容。然而,如果您发现OpenSSL无法解析使用phpecc生成的密钥,请提交一个带有生成密钥时使用参数的问题。

注意:您实际上不需要输出中的公钥部分,它也编码在私钥段中。

获取支持的曲线列表

$ phpecc list-curves
nist-p192
nist-p224
nist-p256
nist-p384
nist-p521
secp256k1
secp384r1
开发者方法

待定...

非对称加密

一个简单的例子
<?php

require 'vendor/autoload.php';

use \Mdanter\Ecc\EccFactory;
use \Mdanter\Ecc\Message\MessageFactory;

$math = EccFactory::getAdapter();
$generator = EccFactory::getNistCurves()->generator256();

// Yeah, you won't really be doing that...
$alice = $generator->createPrivateKey();
$bob = $generator->createPrivateKey();

$messages = new MessageFactory($math);
$message = $messages->plaintext('Not for eavesdroppers', 'sha256');

// Exchange keys
$aliceDh = $alice->createExchange($messages, $bob->getPublicKey());
$bobDh = $bob->createExchange($messages, $alice->getPublicKey());

$encryptedMessage = $aliceDh->encrypt($message);
$decryptedMessage = $bobDh->decrypt($encryptedMessage);

echo $decryptedMessage->getContent() . PHP_EOL;
一个稍微复杂一点的例子

一个更实际的例子,假设你是Alice,并且你的私钥以PEM格式存储在文件中(未加密)。当然,你还需要Bob的以PEM格式存储的公钥。这个例子清楚地表明这个库可以改进...

你想为Bob加密一条消息——只有Bob能够读取。

Alice编码数据
<?php

require 'vendor/autoload.php';

use \Mdanter\Ecc\EccFactory;
use \Mdanter\Ecc\File\PemLoader;
use \Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
use \Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
use \Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
use \Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;
use \Mdanter\Ecc\Message\MessageFactory;

$math = EccFactory::getAdapter();
$messages = new MessageFactory($math);

$loader = new PemLoader();
$privKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
$pubKeySerializer = new PemPublicKeySerializer(new DerPublicKeySerializer());

$alicePrivateKeyPath = '/path/to/alice.priv';
$bobPublicKeyPath = '/path/to/bob.pub';

$alice = $privKeySerializer->parse($loader->loadPrivateKeyData($alicePrivateKeyPath));
$bob = $pubKeySerializer->parse($loader->loadPublicKeyData($bobPublicKeyPath));

$aliceDh = $alice->createExchange($messages, $bob);

$message = $messages->plaintext('To Bob - For your eyes only', 'sha256');
$messageForBob = $aliceDh->encrypt($message);

// Binary!
echo $messageForBob->getContent() . PHP_EOL;

现在你可以将加密后的消息通过电子邮件/平信/等等发送给Bob,他可以解密你的秘密数据(假设他已经有了你的公钥,并且他有他的私钥...)

Bob解密加密后的数据
<?php

require 'vendor/autoload.php';

use \Mdanter\Ecc\File\PemLoader;
use \Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
use \Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
use \Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
use \Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;

$loader = new PemLoader();
$privKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
$pubKeySerializer = new PemPublicKeySerializer(new DerPublicKeySerializer());

$bobPrivateKeyPath = '/path/to/bob/privkey.pem';
$alicePublicKeyPath = '/path/to/alice/publickey.pem';

$alice = $pubKeySerializer->parse($loader->loadPublicKeyData($alicePrivateKeyPath));
$bob = $privKeySerializer->parse($loader->loadPrivateKeyData($bobPublicKeyPath));

$bobDh = $bob->createExchange($alice);
$messageForBob = $bobDh->decrypt('... the encrypted message... too lazy to actually generate the encoded message');