- // ensure that key contains a 32 digit hex string
- return (bool) preg_match('#[0-9a-f]{32}#i', $key);
+ // ensure that key is an alphanumeric string of at least HASH_LENGTH with
+ // an optional underscore+digits at the end.
+ return preg_match('#^[0-9a-zA-Z]{' . self::HASH_LENGTH . ',}+(_\d+)?$#', $key) ? TRUE : FALSE;
+ }
+
+ /**
+ * @param string $name
+ * The name of the form
+ * @return string
+ * A signed digest of $name, computed with the per-session private key
+ */
+ private static function sign($name) {
+ $privateKey = self::privateKey();
+ $sessionID = self::sessionID();
+ $delim = chr(0);
+ if (strpos($sessionID, $delim) !== FALSE || strpos($name, $delim) !== FALSE) {
+ throw new \RuntimeException("Failed to generate signature. Malformed session-id or form-name.");
+ }
+ // The "prefix" gives some advisory details to help with debugging.
+ $prefix = preg_replace('/[^a-zA-Z0-9]/', '', $name);
+ // Note: Unsure why $sessionID is included, but it's always been there, and it doesn't seem harmful.
+ return $prefix . base_convert(hash_hmac(self::HASH_ALGO, $sessionID . $delim . $name, $privateKey), 16, 36);
+