Skip to main content
Version: 4.0

DSA

Loading and saving keys is discussed in Public Keys: Overview.

Supported Formats

  • PKCS1
    • Keys start with -----BEGIN DSA PRIVATE KEY----- or -----BEGIN DSA PUBLIC KEY----- or -----BEGIN DSA PARAMETERS-----
  • PKCS8
    • Keys start with -----BEGIN PRIVATE KEY----- or -----BEGIN ENCRYPTED PRIVATE KEY----- or -----BEGIN PUBLIC KEY-----
  • PuTTY 1
    • Public keys start off with ---- BEGIN SSH2 PUBLIC KEY ----
  • OpenSSH 1
    • Private keys start with -----BEGIN OPENSSH PRIVATE KEY-----
  • XML

A more in-depth discussion of the common formats can be found in Common Key Formats. See Sample DSA Keys for actual samples.

Parameters

Parameters consist of P (prime), Q (group order) and G (group generator). Public and private keys also include Y (public key value) and private keys additionally include X (secret exponent).

PKCS1 is the only format that supports Parameters. They can be extracted from a private or public key by doing $key->getParameters().

Whereas public and private keys are instances of \phpseclib4\Crypt\Common\PublicKey and \phpseclib4\Crypt\Common\PrivateKey, respectively, parameters are an instance of phpseclib4\Crypt\DSA\Parameters (which is what $key->getParameters() returns).

Creating Keys

There are three different ways to create a DSA public / private keypair.

With L and N

Before a private key can be computed DSA needs to know what to use for P (prime), Q (group order) and G (group generator).

Most typically the group generator G is 2 so that's hard-coded.

By providing N (length of group order Q) and L (length of prime P), the remaining requisite values can be generated dynamically.

An example follows:

use phpseclib4\Crypt\DSA;

$L = 2048;
$N = 224;
$private = DSA::createKey($L, $N);
$public = $private->getPublicKey();

Note that if you're trying to create a key for use with SSH2 that N will need to be 160 since, as noted in the footnotes for Supported Formats, that that's all SSH2 supports.

With a Parameters object

With this approach P (prime), Q (group order) and G (group generator) are pre-computed. Either they've been loaded from a -----BEGIN DSA PARAMETERS----- file (or string) or else they've been generated with DSA::createParameters().

Here's an example of doing it using with createParameters:

use phpseclib4\Crypt\DSA;

$private = DSA::createKey(DSA::createParameters(2048, 224));
$public = $private->getPublicKey();

This is basically the same thing as doing DSA::createKey(2048, 224).

Here's an example of creating a key by loading an existant parameters file:

use phpseclib4\Crypt\DSA;
use phpseclib4\Crypt\PublicKeyLoader;

$private = DSA::createKey(PublicKeyLoader::load(file_get_contents('...')));
$public = $private->getPublicKey();

Without any parameters

If no parameters are provided then the default paramters for DSA::createParameters() will be used - L will be 2048 and N will be 224.

An example follows:

use phpseclib4\Crypt\DSA;

$private = DSA::createKey();
$public = $private->getPublicKey();

This is the same thing as doing DSA::createKey(DSA::createParameters()).

Creating / Verifying Signatures

Signatures can be created / verified thusly:

//$private = $private->withSignatureFormat('ASN1');
$signature = $private->sign($message);
echo $private->getPublicKey()->verify($message, $signature) ?
'valid signature' :
'invalid signature';

The signatures generated are not deterministic, as discussed in RFC6979. Such determinism is chiefly of benefit when a CSPRNG is not available and with PHP there is one that's available, exposed via random_bytes().

Signatures have two components - r and s. How these two components are combined to a single string depends on the signature format being employed.

ASN1

This is the default format. ASN1-formatted signatures employee the format discussed in RFC3279. This is the format used by X.509 certificates.

SSH2

SSH2-formatted signatures employee the format discussed in RFC4253.

Raw

Returns an array with r and s as keys.

Key Attributes

$key->getLength() returns an array with L (length of prime P) and N (length of group order Q).

All the with methods have corresponding get methods as follows:

SetterGetter
withHashgetHash
withSignatureFormatgetSignatureFormat

While withHash accepts strings, getHash returns a Hash object (that can be cast to a string via __toString).

Footnotes

  1. The only keys supported by this format are those with an N (length of group order Q) of 160 because that's all SSH2 supports. 2