Decrypt a message with your secret key, that had been encrypted with
your public key by the other endpoint.

@param ResponseInterface $response
@param SealingSecretKey $secretKey
@return ResponseInterface
@throws InvalidMessageException
12089
public function unsealResponse(
        ResponseInterface $response,
        SealingSecretKey $secretKey
    ): ResponseInterface {
        $body = Base64UrlSafe::decode((string) $response->getBody());
        $unsealed = Simple::unseal(
            $body,
            $secretKey
        );
        return $response->withBody($this->adapter->stringToStream($unsealed));
    }
288929
public function decryptStringRequestWithSharedKey(
        RequestInterface $request,
        SharedEncryptionKey $key
    ): string {
        return Simple::decrypt(
            (string) $request->getBody(),
            $key
        );
    }
162624
static SecretKey unwrap(SecretKey kek, byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException {
		final Cipher cipher = CipherSupplier.RFC3394_KEYWRAP.forUnwrapping(kek);
		try {
			return (SecretKey) cipher.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
		} catch (NoSuchAlgorithmException e) {
			throw new IllegalArgumentException("Invalid algorithm: " + wrappedKeyAlgorithm, e);
		}
	}
951228
public function execute(ResponseInterface $response): ResponseInterface
    {
        if ($response->getStatusCode() === self::STATUS_CODE_OK) {
            if (is_null($this->publicKeyServer)) {
                // No installation yet.
                return $response;
            } else {
                $toVerify =
                    $response->getStatusCode() .
                    self::NEWLINE .
                    $this->determineHeaderStringForSignedResponse($response->getHeaders()) .
                    self::NEWLINE . self::NEWLINE .
                    $response->getBody()->getContents();

                $signature = base64_decode($response->getHeaderLine(self::HEADER_SERVER_SIGNATURE));
                $publicKey = $this->publicKeyServer->getKey();

                $signatureResult = openssl_verify($toVerify, $signature, $publicKey, OPENSSL_ALGO_SHA256);

                if ($signatureResult === self::RESULT_SIGNATURE_CORRECT) {
                    return $response;
                } else {
                    throw new SecurityException(self::ERROR_VERIFYING_RESPONSE_FAILED);
                }
            }
        } else {
            return $response;
        }
    }
780507
private function getEncryptionKey(ServerRequestInterface $request) : EncryptionKeyInterface
    {
        if (!$request->hasHeader('x-hashid')) {
            throw new Exception('Unable to decrypt request.');
        }

        $hashKey = $request->getHeaderLine('x-hashid');

        try {
            $result = $this->cache->get($hashKey);

            if (!$result) {
                throw new Exception('Unable to extract key from cache.');
            }

            if (\function_exists('igbinary_unserialize')) {
                return \igbinary_unserialize($result);
            }

            return \unserialize($result);
        } catch (InvalidArgumentException $e) {
            throw new Exception('Unable to decrypt request.', null, $e);
        }
    }
120988
private String decryptInternal(SecretKeySpec key, byte[] encryptedBytes) {
        try {
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM + ENCRYPTION_ALGORITHM_MODIFIER);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, ENCODING);
        } catch (GeneralSecurityException e) {
            throw new RuntimeException("Exception during decryptInternal: " + e, e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Exception during encryptInternal: " + e, e);
        }
    }
137337
private function decodeResponse(ResponseInterface $response): ResponseInterface
    {
        $response = $this->decodeOnEncodingHeader('Transfer-Encoding', $response);

        if ($this->useContentEncoding) {
            $response = $this->decodeOnEncodingHeader('Content-Encoding', $response);
        }

        return $response;
    }
1074326
public function send(RequestInterface $request, MessageInterface $response)
    {
        $cacheKey = $this->generateCacheKeyForRequest($request);

        if ($this->cache->contains($cacheKey)) {
            $this->hits++;

            $cachedResponse = unserialize($this->cache->fetch($cacheKey));
            /* @var $cachedResponse \Buzz\Message\Response */

            $response->setContent($cachedResponse->getContent());
            $response->setHeaders($cachedResponse->getHeaders());

            return;
        }

        $this->misses++;

        $this->client->send($request, $response);

        $this->cache->save($cacheKey, serialize($response), $this->lifetime);
    }
1267278
public static function getSigningPublicKeyFromResponse(string $response) : string
    {
        $version = static::getVersion($response);
        if ($version === 2) {
            if (\strlen($response) < 236) {
                throw new InvalidArgumentException;
            }

            return \substr($response, -160, 32);
        }

        throw new InvalidArgumentException('The response provided is not suitable for public key extraction.');
    }
1178971
public static function retrieve($publickey = null, $secretkey = null)
    {
        return parent::g_retrieve(get_class(), self::getUrl(), $publickey, $secretkey);
    }
991179
public function sealResponse(
        ResponseInterface $response,
        SealingPublicKey $publicKey
    ): ResponseInterface {
        $sealed = Simple::seal(
            (string) $response->getBody(),
            $publicKey
        );
        return $response->withBody(
            $this->adapter->stringToStream(
                Base64UrlSafe::encode($sealed)
            )
        );
    }
1242109
public function unsealJsonRequest(
        RequestInterface $request,
        SealingSecretKey $secretKey
    ): array {
        /** @var array|bool $array */
        $array = \json_decode(
            $this->unsealStringRequest($request, $secretKey),
            true
        );
        if (!\is_array($array)) {
            throw new InvalidMessageException('Could not decode JSON');
        }
        return $array;
    }
1070182
private function decryptRequest(EncryptionKeyInterface $key, ServerRequestInterface $request, string $rawBody, int $version) :? string
    {
        static $response = null;
        static $nonce = null;
        static $publicKey = null;

        $response = new Response(
            $key->getBoxSecretKey()
        );

        if ($version === 1) {
            if (!$request->hasHeader('x-pubkey') || !$request->hasHeader('x-nonce')) {
                throw new Exception('Missing nonce or public key header. Unable to decrypt response.');
            }

            $publicKey = \base64_decode($request->getHeaderLine('x-pubkey'));
            $nonce = \base64_decode($request->getHeaderLine('x-nonce'));
        }

        $decryptedRequest = $response->decrypt(
            $rawBody,
            $publicKey,
            $nonce
        );

        $hashKey = $request->getHeaderLine('x-hashid');
        if ($key->isEphemeral()) {
            $this->cache->delete($hashKey);
        }

        return $decryptedRequest;
    }
404470
public function encrypt($data, Key $key)
	{
		// Validate key.
		if ($key->getType() !== 'sodium')
		{
			throw new InvalidKeyTypeException('sodium', $key->getType());
		}

		if (!$this->nonce)
		{
			throw new \RuntimeException('Missing nonce to decrypt data');
		}

		return Compat::crypto_box(
			$data,
			$this->nonce,
			Compat::crypto_box_keypair_from_secretkey_and_publickey($key->getPrivate(), $key->getPublic())
		);
	}
1282466
public function onError( ResponseInterface $response, RequestInterface $request ) {
        $json = $this->getResponseAsJson( $response );
        if( !is_null( $json ) && isset( $json->text )) {
            if( $json->text === 'invalid key' ||  $json->text === 'endpoint requires authentication' ) {
                throw new AuthenticationException( $json->text, $response );
            } elseif( preg_match('/^requires scope (.*)$/', $json->text, $match )) {
                throw new InvalidPermissionsException( $json->text, $match[1], $response );
            }
        }
    }
1088123
public static function getPublicKeyFromResponse(string $response) : string
    {
        $version = static::getVersion($response);
        if ($version === 2) {
            if (\strlen($response) < 236) {
                throw new InvalidArgumentException;
            }

            return \substr($response, 28, 32);
        }

        throw new InvalidArgumentException('The response provided is not suitable for public key extraction.');
    }
151044
public function decryptJsonResponseWithSharedKey(
        ResponseInterface $response,
        SharedEncryptionKey $key
    ): array {
        $decrypted = $this->decryptResponseWithSharedKey(
            $response,
            $key
        );

        /** @var array|bool $array */
        $array = \json_decode(
            (string) $decrypted->getBody(),
            true
        );
        if (!\is_array($array)) {
            throw new InvalidMessageException('Could not decode JSON');
        }
        return $array;
    }