type !== 'sodium') { throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected sodium.'); } if (!$this->nonce) { throw new RuntimeException('Missing nonce to decrypt data'); } $decrypted = ParagonIE_Sodium_Compat::crypto_box_open( $data, $this->nonce, ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($key->private, $key->public) ); if ($decrypted === false) { throw new RuntimeException('Malformed message or invalid MAC'); } return $decrypted; } /** * Method to encrypt a data string. * * @param string $data The data string to encrypt. * @param JCryptKey $key The key object to use for encryption. * * @return string The encrypted data string. * * @throws RuntimeException */ public function encrypt($data, JCryptKey $key) { // validate key if ($key->type !== 'sodium') { throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected sodium.'); } if (!$this->nonce) { throw new RuntimeException('Missing nonce to decrypt data'); } return ParagonIE_Sodium_Compat::crypto_box( $data, $this->nonce, ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($key->private, $key->public) ); } /** * Method to generate a new encryption key object. * * @param array $options Key generation options. * * @return JCryptKey * * @throws RuntimeException */ public function generateKey(array $options = []) { // Generate the encryption key. $pair = ParagonIE_Sodium_Compat::crypto_box_keypair(); return new JCryptKey( 'sodium', ParagonIE_Sodium_Compat::crypto_box_secretkey($pair), ParagonIE_Sodium_Compat::crypto_box_publickey($pair) ); } /** * Check if the cipher is supported in this environment. * * @return bool */ public static function isSupported(): bool { return class_exists(ParagonIE_Sodium_Compat::class); } /** * Set the nonce to use for encrypting/decrypting messages * * @param string $nonce The message nonce * * @return void */ public function setNonce($nonce) { if (strlen($nonce) < ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES) { $nonce = str_repeat($nonce, ceil(ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES / strlen($nonce))); } $this->nonce = substr($nonce, 0, ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES); } }