35 private const CHECKSUM_ALGO =
"sha256";
37 public static bool $ENABLED =
true;
41 private Cipher $decryptCipher;
42 private int $decryptCounter = 0;
44 private Cipher $encryptCipher;
45 private int $encryptCounter = 0;
47 public function __construct(
string $encryptionKey,
string $algorithm,
string $iv){
48 $this->key = $encryptionKey;
50 $this->decryptCipher =
new Cipher($algorithm);
51 $this->decryptCipher->decryptInit($this->key, $iv);
53 $this->encryptCipher =
new Cipher($algorithm);
54 $this->encryptCipher->encryptInit($this->key, $iv);
67 public static function fakeGCM(
string $encryptionKey) : self{
71 substr($encryptionKey, 0, 12) .
"\x00\x00\x00\x02"
75 public static function cfb8(
string $encryptionKey) : self{
79 substr($encryptionKey, 0, 16)
86 public function decrypt(
string $encrypted) : string{
87 if(strlen($encrypted) < 9){
90 $decrypted = $this->decryptCipher->decryptUpdate($encrypted);
91 $payload = substr($decrypted, 0, -8);
93 $packetCounter = $this->decryptCounter++;
95 if(($expected = $this->calculateChecksum($packetCounter, $payload)) !== ($actual = substr($decrypted, -8))){
96 throw new DecryptionException(
"Encrypted packet $packetCounter has invalid checksum (expected " . bin2hex($expected) .
", got " . bin2hex($actual) .
")");
102 public function encrypt(
string $payload) : string{
103 return $this->encryptCipher->encryptUpdate($payload . $this->calculateChecksum($this->encryptCounter++, $payload));
106 private function calculateChecksum(
int $counter,
string $payload) : string{
107 $hash = openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true);
109 throw new \RuntimeException(
"openssl_digest() error: " . openssl_error_string());
111 return substr($hash, 0, 8);
static fakeGCM(string $encryptionKey)