Skip to content

Encrypted URIs

Greg Bowler edited this page Apr 19, 2026 · 1 revision

One of the main usages of this library is the URI workflow. Instead of transmitting cipher text and IV as separate values, we can embed them directly into a URI.

This is useful for:

  • redirects between applications
  • links sent between trusted systems
  • callback URLs that need to carry a small encrypted payload

Creating an encrypted URI

Start with a normal encrypted message flow:

use GT\Cipher\Key;
use GT\Cipher\Message\PlainTextMessage;

$key = new Key();
$message = new PlainTextMessage("Signed in as account 105");
$cipherText = $message->encrypt($key);

Then append the encrypted values to a base URI:

$uri = $cipherText->getUri("https://example.com/receiver.php");
echo $uri;

The returned URI will contain two query string parameters:

  • cipher
  • iv

If the base URI already has a query string, those values are added alongside the existing parameters.

Decrypting from the incoming URI

On the receiving side, construct EncryptedUri from the request URI:

use GT\Cipher\EncryptedUri;

$encryptedUri = new EncryptedUri((string)$uri);
$plainText = $encryptedUri->decryptMessage($key);

echo $plainText;

decryptMessage() returns a PlainTextMessage.

Using custom query string parameter names

If cipher and iv do not fit the surrounding application, we can supply custom names:

$encryptedUri = new EncryptedUri(
	$requestUri,
	"payload",
	"rand",
);

The constructor then expects those parameter names instead of the defaults.

Missing parameter behaviour

If either required parameter is absent or empty, Cipher throws MissingQueryStringException.

That helps distinguish:

  • malformed links
  • tampered links
  • requests that were never meant for this decrypting endpoint

URI safety notes

Encrypting a message does not make a URI invisible. The full URL may still be stored in:

  • browser history
  • access logs
  • proxy logs
  • analytics tools

Cipher protects the message content, but we should still think carefully before placing sensitive data in any URL.

For highly sensitive flows, POST bodies or server-side session state may still be the better transport choice.


For a closer look at the small helper objects used throughout the library, continue to Key and IV objects.

Clone this wiki locally