Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ECDSA / EdDSA support #1322

Merged
merged 6 commits into from Dec 16, 2018
Merged

add ECDSA / EdDSA support #1322

merged 6 commits into from Dec 16, 2018

Conversation

terrafrost
Copy link
Member

What's New

This commit adds support for the following curves:

(SECG stands for Standards for Efficient Cryptography)

For Ed25519, libsodium is used. If libsodium (or sodium_compat) is not available a fallback PHP implementation is used. For the SECG and Brainpool curves, OpenSSL is used. If OpenSSL is not available a fallback PHP implementation is used.

The following key formats are supported:

  • ASN1
    • private keys start off with -----BEGIN EC PRIVATE KEY-----
    • supports both named and specified curves.
  • PKCS8
    • private keys start off with -----BEGIN PRIVATE KEY----- or -----BEGIN ENCRYPTED PRIVATE KEY-----
    • supports both named and specified curves.
  • OpenSSH
    • encrypted keys are not supported as PHP is far to slow for a pure-PHP bcrypt implementation (see Crypt\ECDSA\Keys\OpenSSH.php for details)
  • libsodium
  • XML

Examples

Creating keys:

use phpseclib\Crypt\ECDSA;

extract(ECDSA::createKey('Ed25519'));
//extract(ECDSA::createKey('nistp256'));

//$privatekey->setKeyFormat('PuTTY');
//$publickey->setKeyFormat('OpenSSH');

echo $privatekey . "\n\n" . $publickey;

Retrieving key information:

use phpseclib\Crypt\ECDSA;

$key = new ECDSA();
$key->load('...');

echo $key->getCurve();

Creating / verifying signatures:

use phpseclib\Crypt\ECDSA;

$privatekey = new ECDSA();
$privatekey->load('...');

$publickey = $privatekey->getPublicKey();

$sig = $privatekey->sign('zzz');
echo $publickey->verify('zzz', $sig) ? 'good' : 'bad';

To test with / without the pure-PHP engines (more useful for unit testing than anything):

use phpseclib\Crypt\ECDSA;

ECDSA::useInternalEngine(); // uses PHP engine

// do stuff

ECDSA::useBestEngine(); // use OpenSSL / libsodium, if available; otherwise, PHP engine

// do stuff

Setting the Engine in AsymmetricCipher vs BigInteger vs SymmetricCipher

In BigInteger you set the engine thusly:

BigInteger::setEngine('PHP64'); // PHP32, BCMath, GMP also supported

In SymmetricKey (and all the classes that extend it) you set the engine thusly:

$aes->setPreferredEngine('PHP'); // Eval, mcrypt, OpenSSL also supported

In AsymmetricKey (and all the classes that extend it) you set the engine thusly:

ECDSA::useBestEngine();

So why is it that the engine is set differently for each one?

SymmetricKey

The engine is set on a per object basis, instead of globally, because the engine ultimately depends on the cipher, the mode of operation, the key length, etc. If you have two SymmetricKey instances it may very well be the case that one of them is using the OpenSSL engine while the other is using the Eval engine.

It's setPreferredEngine because the fact that you want to use OpenSSL doesn't necessarily mean that OpenSSL is going to be available for you to use.

AsymmetricKey

The engine ultimately depends on the curve being utilized. Since there are, at most, two supported engines for any given curve, we can call them the "best" engine and the "internal" (ie. worst) engine. This approach doesn't work with SymmetricKey since an object can simultaneously support up to four different engines (OpenSSL, mcrypt, Eval, PHP).

BigInteger

Whereas with SymmetricKey and AsymmetricKey it may be necessary to use separate engines for different instances of either, with BigInteger, there's no reason why every possible instance can't utilize the same engine.

@eimann
Copy link

eimann commented Jan 31, 2019

Hi, this is not visible in 1.0.14 yet - any idea when this will be available in a release? Thanks!

@bantu
Copy link
Member

bantu commented Jan 31, 2019

@eimann It is my understanding that this will become available in 3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants