. */ namespace SP\Core\Crypt; use RuntimeException; /** * Class Vault * * @package SP\Core\Crypt */ final class Vault { private ?string $data = null; private ?string $key = null; private int $timeSet = 0; private function __construct(private CryptInterface $crypt) {} public static function factory(CryptInterface $crypt): Vault { return new self($crypt); } /** * Re-key this vault * * @throws \SP\Core\Exceptions\CryptException */ public function reKey(string $newSeed, string $oldSeed): Vault { return $this->saveData($this->getData($oldSeed), $newSeed); } /** * Create a new vault with the saved data * * @throws \SP\Core\Exceptions\CryptException */ public function saveData($data, string $key): Vault { $vault = new Vault($this->crypt); $vault->timeSet = time(); $vault->key = $this->crypt->makeSecuredKey($key); $vault->data = $this->crypt->encrypt($data, $vault->key, $key); return $vault; } /** * Get the data decrypted * * @throws \SP\Core\Exceptions\CryptException */ public function getData(string $key): string { if ($this->data === null || $this->key === null) { throw new RuntimeException('Either data or key must be set'); } return $this->crypt->decrypt($this->data, $this->key, $key); } /** * Serialize the current vault */ public function getSerialized(): string { return serialize($this); } /** * Get the last time the key and data were set * * @return int */ public function getTimeSet(): int { return $this->timeSet; } }