You mean like a long-term "remember me" authentication cookie? A random token and a lookup table is generally the best way to approach that. (The linked article also delves into some "proactively secure" strategies.) I made a similar argument in favor of random tokens rather than cryptography features when discussing URL parameter encryption, and touched on it when discussing PHP session security.
Let's look more broadly: You want to store information in a cookie (which the user can spoof/tamper with as they please). You don't want the user to be able to, upon changing the cookie, get any meaningful/useful result. (Ideally, your code would just go, "This isn't right," and treat them as unauthenticated.)
The answer is to use authenticated encryption. There are two libraries that offer a simple and easy way to satisfy this (disclaimer: I contribute to both, so you should ask a cryptography expert before thinking about using either).
Halite
Halite (first stable release coming soon) is a PHP library that wraps the PHP bindings for libsodium to make it easier to use. One of the classes it comes with out of the box is, quite simply, \ParagonIE\Halite\Cookie
.
Note that Halite requires the PHP extension for libsodium (available in PECL). If that's a no-go, then you probably want...
Defuse Security's PHP Encryption Library
Most commonly known by its name on Packagist, defuse/php-encryption, this works out-of-the-box with PHP 5.4+.
Version 2 is coming out soon, but if you need a solution today, grab version 1.2.1 and simply do this:
$enc_key = Crypto::CreateNewRandomKey(); // Store me!
// Storing a cookie:
setcookie(
'name',
Crypto::binToHex(Crypto::encrypt($value, $enc_key))
// other parameters
);
// Reading a cookie
try {
$cdata = Crypto::decrypt(
Crypto::hexToBin($_COOKIE['name']),
$enc_key
);
} catch (Exception $e) {
$cdata = null;
}