Ejemplo n.º 1
0
    /**
     * Compute the shared secret key based on the public key received from the
     * the second party to this transaction. This should agree to the secret
     * key the second party computes on our own public key.
     * Once in agreement, the key is known to only to both parties.
     * By default, the function expects the public key to be in binary form
     * which is the typical format when being transmitted.
     *
     * If you need the binary form of the shared secret key, call
     * getSharedSecretKey() with the optional parameter for Binary output.
     *
     * @param string $publicKey
     * @param string $publicKeyFormat
     * @param string $secretKeyFormat
     * @return string
     * @throws \Zend\Crypt\Exception\InvalidArgumentException
     * @throws \Zend\Crypt\Exception\RuntimeException
     */
    public function computeSecretKey($publicKey, $publicKeyFormat = self::FORMAT_NUMBER,
                                                 $secretKeyFormat = self::FORMAT_NUMBER)
    {
        if (function_exists('openssl_dh_compute_key') && self::$useOpenssl !== false) {
            $publicKey = $this->convert($publicKey, $publicKeyFormat, self::FORMAT_BINARY);
            $secretKey = openssl_dh_compute_key($publicKey, $this->opensslKeyResource);
            if (false === $secretKey) {
                throw new Exception\RuntimeException(
                    'Can not compute key; openssl ' . openssl_error_string()
                );
            }
            $this->secretKey = $this->convert($secretKey, self::FORMAT_BINARY, self::FORMAT_NUMBER);
        } else {
            $publicKey = $this->convert($publicKey, $publicKeyFormat, self::FORMAT_NUMBER);
            if (!preg_match('/^\d+$/', $publicKey)) {
                throw new Exception\InvalidArgumentException(
                    'Invalid parameter; not a positive natural number'
                );
            }
            $this->secretKey = $this->math->powmod($publicKey, $this->getPrivateKey(), $this->getPrime());
        }

        return $this->getSharedSecretKey($secretKeyFormat);
    }