[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * DSA Private Key 5 * 6 * @author Jim Wigginton <terrafrost@php.net> 7 * @copyright 2015 Jim Wigginton 8 * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 * @link http://phpseclib.sourceforge.net 10 */ 11 12 namespace phpseclib3\Crypt\DSA; 13 14 use phpseclib3\Crypt\Common; 15 use phpseclib3\Crypt\DSA; 16 use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; 17 use phpseclib3\Math\BigInteger; 18 19 /** 20 * DSA Private Key 21 * 22 * @author Jim Wigginton <terrafrost@php.net> 23 */ 24 final class PrivateKey extends DSA implements Common\PrivateKey 25 { 26 use Common\Traits\PasswordProtected; 27 28 /** 29 * DSA secret exponent x 30 * 31 * @var \phpseclib3\Math\BigInteger 32 */ 33 protected $x; 34 35 /** 36 * Returns the public key 37 * 38 * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key 39 * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. 40 * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this 41 * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g 42 * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified 43 * by getting a DSA PKCS8 public key: 44 * 45 * "openssl dsa -in private.dsa -pubout -outform PEM" 46 * 47 * ie. just swap out rsa with dsa in the rsa command above. 48 * 49 * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA 50 * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature 51 * without the parameters and the PKCS1 DSA public key format does not include the parameters. 52 * 53 * @see self::getPrivateKey() 54 * @return mixed 55 */ 56 public function getPublicKey() 57 { 58 $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); 59 60 if (!isset($this->y)) { 61 $this->y = $this->g->powMod($this->x, $this->p); 62 } 63 64 $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); 65 66 return DSA::loadFormat('PKCS8', $key) 67 ->withHash($this->hash->getHash()) 68 ->withSignatureFormat($this->shortFormat); 69 } 70 71 /** 72 * Create a signature 73 * 74 * @see self::verify() 75 * @param string $message 76 * @return mixed 77 */ 78 public function sign($message) 79 { 80 $format = $this->sigFormat; 81 82 if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { 83 $signature = ''; 84 $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); 85 86 if ($result) { 87 if ($this->shortFormat == 'ASN1') { 88 return $signature; 89 } 90 91 extract(ASN1Signature::load($signature)); 92 93 return $format::save($r, $s); 94 } 95 } 96 97 $h = $this->hash->hash($message); 98 $h = $this->bits2int($h); 99 100 while (true) { 101 $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); 102 $r = $this->g->powMod($k, $this->p); 103 list(, $r) = $r->divide($this->q); 104 if ($r->equals(self::$zero)) { 105 continue; 106 } 107 $kinv = $k->modInverse($this->q); 108 $temp = $h->add($this->x->multiply($r)); 109 $temp = $kinv->multiply($temp); 110 list(, $s) = $temp->divide($this->q); 111 if (!$s->equals(self::$zero)) { 112 break; 113 } 114 } 115 116 // the following is an RFC6979 compliant implementation of deterministic DSA 117 // it's unused because it's mainly intended for use when a good CSPRNG isn't 118 // available. if phpseclib's CSPRNG isn't good then even key generation is 119 // suspect 120 /* 121 $h1 = $this->hash->hash($message); 122 $k = $this->computek($h1); 123 $r = $this->g->powMod($k, $this->p); 124 list(, $r) = $r->divide($this->q); 125 $kinv = $k->modInverse($this->q); 126 $h1 = $this->bits2int($h1); 127 $temp = $h1->add($this->x->multiply($r)); 128 $temp = $kinv->multiply($temp); 129 list(, $s) = $temp->divide($this->q); 130 */ 131 132 return $format::save($r, $s); 133 } 134 135 /** 136 * Returns the private key 137 * 138 * @param string $type 139 * @param array $options optional 140 * @return string 141 */ 142 public function toString($type, array $options = []) 143 { 144 $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); 145 146 if (!isset($this->y)) { 147 $this->y = $this->g->powMod($this->x, $this->p); 148 } 149 150 return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); 151 } 152 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body