TL;DR You should use format-preserving encryption which is designed to solve your problem.
There are various solutions some of which are easier than others to implement. I'll estimate their sizes based on your example token and url.
Some less than perfect solutions
As suggested in the comments, a bitwise stream cipher (such as ChaCha) or block cipher in streaming mode (such as AES-CTR) followed by base 64 encoding and url tokenising will only make your string about 42% longer plus any IV overhead. You may or may not want to worry about the ability of the user to modify the data. A user who can identify their token data could then forge tokens of the same or shorter length.
Estimated token length with 128-bit IV: 61 characters.
Estimated url length: 92 characters.
By adding a MAC you can defend against token manipulation but add another 21-22 characters to both lengths. Modern authenticated encryption methods may integrate authentication codes automatically.
You can shave off some characters with shorter IVs and MACs, but I wouldn't recommend going below 64-bits. These would save you 10-11 characters.
Estimated token length with 64-bit IV: 50 characters (61 with 64-bit MAC).
Estimated url length: 81 characters (92 with 64-bit MAC).
If we assume that your tokens use a character set of size 65 {A-Za-z0-9@|.
} You could index the set and use a mod 65 stream cipher which would preserve the character set. Again IVs and MACs would be advisable, but could be expressed in the character set. There aren't any off the shelf mod 65 stream ciphers, but one could be constructed based on established stream cipher designs.
Estimated token length: 40 characters (52 with short MAC)
Estimated url length: 71 characters (73 with short MAC)
My laptop browser has a 65 character address bar and so I like urls with fewer than 64 characters to inhibit malicious url suffixes such as @http://evil.com/malware.exe. None of these solutions manage to achieve this for your example.
The designed and standardised solution
You can create url-friendly tokens and then use format-preserving encryption for 0 overhead. NIST have a standard for FPE and googling for "FF3-1 open source" should find an implementation in your language of choice.
Estimated token length: 27 characters
Estimated url length: 58 characters
58 character urls are still longer than the address bar on my phone browser, but this is still pretty good.
RijndealManaged
will just perform AES by default (although block sizes of 192 and 256 seem available as well, and the other 32 bit increments are not). There seems to be an unhealthy tendency to go for implementation classes instead of e.g.Aes.Create()
although different platforms may have different sets of classes. $\endgroup$Unicode
encoding (a misnomer of UTF16LE for our non-programmers) or performing base64 encoding followed by URL encoding. Presuming symmetric encryption of course. $\endgroup$