|
| 1 | +# hejunjie/encrypted-request |
| 2 | + |
| 3 | +<div align="center"> |
| 4 | + <a href="./README.md">English</a>|<a href="./README.zh-CN.md">简体中文</a> |
| 5 | + <hr width="50%"/> |
| 6 | +</div> |
| 7 | + |
| 8 | +A PHP package for request encryption, designed for quickly implementing secure communication between frontend and backend. |
| 9 | + |
| 10 | +In real-world development, there are often scenarios where requests need extra security: data must be encrypted to prevent sniffing, and requests should be protected against tampering or replay attacks. Coordinating encryption methods and signature rules with frontend teams each time can be cumbersome. To simplify this workflow, I created this PHP package and a companion npm package, allowing frontend developers to generate encrypted request parameters with a single function call, making it easy to implement secure API communication. |
| 11 | + |
| 12 | +Frontend companion npm package: [npm-encrypted-request](https://github.com/zxc7563598/npm-encrypted-request) |
| 13 | + |
| 14 | +**This project has been parsed by Zread. If you need a quick overview of the project, you can click here to view it:[Understand this project](https://zread.ai/zxc7563598/php-encrypted-request)** |
| 15 | + |
| 16 | +## Features |
| 17 | + |
| 18 | +- 🔐 AES-128-CBC decryption of frontend-encrypted data to prevent leaks |
| 19 | +- ✍️ Dynamic MD5 signature verification to prevent forged signatures |
| 20 | +- ⏰ Timestamp validation (in seconds) with configurable tolerance, to prevent request hijacking |
| 21 | +- ⚙️ Configurable via `.env` file or array |
| 22 | +- 🧩 Extensible with custom decryptors |
| 23 | + |
| 24 | +## Installation |
| 25 | + |
| 26 | +```bash |
| 27 | +composer require hejunjie/encrypted-request |
| 28 | +``` |
| 29 | + |
| 30 | +## Configuration Example |
| 31 | + |
| 32 | +You can configure via `.env` file: |
| 33 | + |
| 34 | +```dotenv |
| 35 | +APP_KEY=your-app-key |
| 36 | +DEFAULT_TIMESTAMP_DIFF=60 |
| 37 | +
|
| 38 | +# Optional when using a custom decryptor |
| 39 | +AES_KEY=your-aes-key |
| 40 | +AES_IV=your-aes-iv |
| 41 | +``` |
| 42 | + |
| 43 | +Or pass configuration as an array: |
| 44 | + |
| 45 | +```php |
| 46 | +$config = [ |
| 47 | + 'APP_KEY' => 'your-app-key', // Required: key used for signature verification (32 alphanumeric characters) |
| 48 | + 'DEFAULT_TIMESTAMP_DIFF' => 60, // Required: maximum allowed timestamp difference in seconds |
| 49 | + 'AES_KEY' => 'your-aes-key', // Optional: AES encryption key (16 characters); not needed for custom decryptor |
| 50 | + 'AES_IV' => 'your-aes-iv' // Optional: AES initialization vector (16 characters); not needed for custom decryptor |
| 51 | +]; |
| 52 | +``` |
| 53 | + |
| 54 | +## Usage |
| 55 | + |
| 56 | +### Basic Example |
| 57 | + |
| 58 | +```php |
| 59 | +use Hejunjie\EncryptedRequest\EncryptedRequestHandler; |
| 60 | + |
| 61 | +$param = $_POST; // Fetch frontend request parameters |
| 62 | + |
| 63 | +$handler = new EncryptedRequestHandler(); |
| 64 | +try { |
| 65 | + $data = $handler->handle( |
| 66 | + $param['en_data'] ?? '', |
| 67 | + $param['timestamp'] ?? '', |
| 68 | + $param['sign'] ?? '' |
| 69 | + ); |
| 70 | + // $data contains the decrypted array |
| 71 | +} catch (\Hejunjie\EncryptedRequest\Exceptions\SignatureException $e) { |
| 72 | + echo "Signature error: " . $e->getMessage(); |
| 73 | +} catch (\Hejunjie\EncryptedRequest\Exceptions\TimestampException $e) { |
| 74 | + echo "Timestamp error: " . $e->getMessage(); |
| 75 | +} catch (\Hejunjie\EncryptedRequest\Exceptions\DecryptionException $e) { |
| 76 | + echo "Decryption error: " . $e->getMessage(); |
| 77 | +} |
| 78 | +``` |
| 79 | + |
| 80 | +### Custom Decryptor |
| 81 | + |
| 82 | +> In most cases, if your `AES_KEY`, `AES_IV`, and `APP_KEY` remain confidential, the default AES-128-CBC decryption is sufficient for secure API communication. |
| 83 | +
|
| 84 | +> Custom decryptors are mainly for special scenarios, such as using a completely different encryption algorithm or requiring higher security standards. |
| 85 | +
|
| 86 | +> If your project demands extremely high confidentiality, it is recommended to design your own encryption rules rather than relying solely on the default AES implementation. |
| 87 | +
|
| 88 | +```php |
| 89 | +class MyCustomDecryptor implements \Hejunjie\EncryptedRequest\Contracts\DecryptorInterface |
| 90 | +{ |
| 91 | + /** |
| 92 | + * Decrypt method |
| 93 | + * |
| 94 | + * @param string $data Encrypted data |
| 95 | + * |
| 96 | + * @return array Decrypted array |
| 97 | + * @throws \Hejunjie\EncryptedRequest\Exceptions\DecryptionException |
| 98 | + */ |
| 99 | + public function decrypt(string $data): array |
| 100 | + { |
| 101 | + // Custom decryption logic |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +$customDecryptor = new MyCustomDecryptor(); |
| 106 | +$handler = new EncryptedRequestHandler($customDecryptor); |
| 107 | +``` |
| 108 | + |
| 109 | +## Frontend Integration |
| 110 | + |
| 111 | +Frontend can use the [hejunjie-encrypted-request](https://github.com/zxc7563598/npm-encrypted-request) npm package to generate encrypted data and send it to the PHP backend: |
| 112 | + |
| 113 | +```typescript |
| 114 | +import { encryptRequest } from "hejunjie-encrypted-request"; |
| 115 | + |
| 116 | +const encrypted = encryptRequest( |
| 117 | + { message: "Hello" }, |
| 118 | + { |
| 119 | + appKey: "your-app-key", |
| 120 | + aesKey: "your-aes-key", |
| 121 | + aesIv: "your-aes-iv", |
| 122 | + token: "your-token", |
| 123 | + } |
| 124 | +); |
| 125 | +``` |
| 126 | + |
| 127 | +The PHP backend can directly use `EncryptedRequestHandler` to decrypt. |
| 128 | + |
| 129 | +## Notes |
| 130 | + |
| 131 | +1. AES key and IV must be 16 characters. |
| 132 | +2. Timestamp is in seconds; `DEFAULT_TIMESTAMP_DIFF` is the maximum allowed difference. Be mindful of time zones. |
| 133 | +3. Frontend `appKey`, `aesKey`, and `aesIv` must match backend, otherwise signature verification will fail. |
| 134 | +4. `token` is optional and will be passed together with encrypted data. |
| 135 | + |
| 136 | +## Compatibility |
| 137 | + |
| 138 | +- PHP \>\= 8.1 |
| 139 | +- Compatible with any PSR-4 autoloading framework or plain PHP project |
| 140 | + |
| 141 | +## Development & Contribution |
| 142 | + |
| 143 | +Feel free to submit issues or pull requests, contribute new decryptors, optimize functionality, or add examples. |
0 commit comments