├── composer.json ├── LICENSE ├── src └── Cryptor.php └── README.md /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lazervel/cryptor", 3 | "description": "Cryptor is a PHP library for easy and secure data encryption and decryption.", 4 | "type": "library", 5 | "keywords": ["Cryptor", "codec", "encrypt", "decrypt", "lazervel", "php"], 6 | "license": "MIT", 7 | "autoload": { 8 | "psr-4": { 9 | "Lazervel\\Cryptor\\": "src/" 10 | } 11 | }, 12 | "require": { 13 | "php": "^7.2 || ^8.0" 14 | }, 15 | "homepage": "https://github.com/lazervel", 16 | "authors": [ 17 | { 18 | "name": "Indian Modassir", 19 | "email": "indianmodassir@gmail.com", 20 | "homepage": "https://github.com/indianmodassir" 21 | } 22 | ], 23 | "repositories": [ 24 | { 25 | "type": "composer", 26 | "url": "https://repo.packagist.org" 27 | } 28 | ], 29 | "funding": [ 30 | { 31 | "type": "Github", 32 | "url": "https://github.com/sponsors/indianmodassir" 33 | } 34 | ], 35 | "minimum-stability": "stable" 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 The Lazervel Framework 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Cryptor.php: -------------------------------------------------------------------------------- 1 | key = \hash('sha256', $raw, true); 39 | } 40 | 41 | /** 42 | * Encrypts plain text data using AES-256-GCM or the specified cipher. 43 | * 44 | * @param string $data [required] 45 | * @param string|null $cipher [optional] 46 | * @param string $add [optional] 47 | * 48 | * @return string|false Base64-encoded encrypted payload on success, or false on failure. 49 | * @throws \InvalidArgumentException If the selected cipher is invalid. 50 | */ 51 | public function encrypt(string $data, ?string $cipher = null, string $add = '') 52 | { 53 | $tag = ''; 54 | $cipher = $cipher ?? 'aes-256-gcm'; 55 | $ivLen = \openssl_cipher_iv_length($cipher); 56 | 57 | if ($ivLen === false || $ivLen <= 0) { 58 | throw new \InvalidArgumentException('Invalid cipher selected.'); 59 | } 60 | 61 | $iv = \random_bytes($ivLen); 62 | $encrypted = \openssl_encrypt($data, $cipher, $this->key, \OPENSSL_RAW_DATA, $iv, $tag, $add); 63 | 64 | // In-Case failed encryption 65 | if (!$encrypted) return false; 66 | 67 | return \base64_encode(\json_encode([ 68 | 'iv' => \base64_encode($iv), 69 | 'value' => \base64_encode($encrypted), 70 | 'cipher' => \base64_encode($cipher), 71 | 'tag' => \base64_encode($tag ?? '') 72 | ])); 73 | } 74 | 75 | /** 76 | * Verifies whether the given encrypted value matches the provided plain text. 77 | * 78 | * @param string $plain [required] 79 | * @param string $encrypted [required] 80 | * @param string $add [optional] 81 | * 82 | * @return bool True if verification succeeds (data matches), false otherwise. 83 | */ 84 | public function verify(string $plain, string $encrypted, string $add = '') : bool 85 | { 86 | $data = $this->decrypt($encrypted, $add); 87 | return $data !== false && \hash_equals($data, $plain); 88 | } 89 | 90 | /** 91 | * Decrypts encrypted data previously encrypted with {@see encrypt()}. 92 | * 93 | * @param string $data [required] 94 | * @param string $add [optional] 95 | * 96 | * @return string|false The decrypted plain text on success, or false if decryption fails. 97 | */ 98 | public function decrypt(string $data, string $add = '') 99 | { 100 | $data = \json_decode(\base64_decode($data), true); 101 | 102 | if (!\is_array($data) || !isset($data['iv'], $data['value'], $data['cipher'])) { 103 | return false; 104 | } 105 | 106 | $tag = isset($data['tag']) ? base64_decode($data['tag']) : ''; 107 | $value = \base64_decode($data['value']); 108 | $iv = \base64_decode($data['iv']); 109 | $cipher = \base64_decode($data['cipher']); 110 | 111 | return \openssl_decrypt($value, $cipher, $this->key, \OPENSSL_RAW_DATA, $iv, $tag, $add); 112 | } 113 | 114 | /** 115 | * Prevents serialization of sensitive data. 116 | * 117 | * @return array An empty array to avoid exposing sensitive information. 118 | */ 119 | public function __sleep() : array 120 | { 121 | return []; 122 | } 123 | 124 | /** 125 | * Controls what is displayed during debugging (e.g., var_dump()). 126 | * 127 | * @return array An array hiding the encryption key from output. 128 | */ 129 | public function __debugInfo(): array 130 | { 131 | return ['key' => '']; 132 | } 133 | 134 | /** 135 | * Destructor to securely erase the encryption key from memory. 136 | */ 137 | public function __destruct() 138 | { 139 | $this->key = ''; 140 | } 141 | } 142 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cryptor 2 | 3 | A lightweight and secure PHP encryption library that provides modern **AES-256-GCM** authenticated encryption and decryption with optional AAD (Additional Authenticated Data) support. 4 | It is designed to be **simple, dependency-free**, and compatible with any PHP application or framework. 5 | 6 | --- 7 | 8 | ## Features 9 | 10 | - ✅ AES-256-GCM authenticated encryption 11 | - ✅ Optional AAD (Additional Authenticated Data) 12 | - ✅ Secure key handling & memory cleanup 13 | - ✅ JSON + Base64 encoded output 14 | - ✅ Key derived safely from `APP_KEY` or custom string 15 | - ✅ No framework dependency (works in plain PHP or Laravel) 16 | 17 | --- 18 | 19 | ## Installation 20 | 21 | Use Composer (recommended): 22 | 23 | ```bash 24 | composer require lazervel/cryptor 25 | ``` 26 | 27 | Or manually include it: 28 | 29 | ```php 30 | require_once 'src/Cryptor.php'; 31 | ``` 32 | 33 | --- 34 | 35 | ## ⚙️ Environment Setup 36 | 37 | Set your application key in `.env` or environment variables: 38 | 39 | ```env 40 | APP_KEY=base64:your-secret-key 41 | ``` 42 | 43 | Alternatively, you can provide a custom key directly when creating an instance. 44 | 45 | --- 46 | 47 | ## 🧠 Basic Usage 48 | 49 | ```php 50 | encrypt('Hello World!'); 59 | echo "Encrypted: " . $encrypted . PHP_EOL; 60 | 61 | // Decrypt the message 62 | $decrypted = $cryptor->decrypt($encrypted); 63 | echo "Decrypted: " . $decrypted . PHP_EOL; 64 | 65 | // Verify that data matches 66 | if ($cryptor->verify('Hello World!', $encrypted)) { 67 | echo "✅ Data verified successfully!"; 68 | } else { 69 | echo "❌ Verification failed!"; 70 | } 71 | ``` 72 | 73 | --- 74 | 75 | ## 🧩 With Additional Authenticated Data (AAD) 76 | 77 | You can attach additional data (not encrypted but authenticated): 78 | 79 | ```php 80 | $add = 'payment#RZP123'; // example reference 81 | 82 | $encrypted = $cryptor->encrypt('Sensitive Transaction Data', 'aes-256-gcm', $add); 83 | 84 | // Must use same $add while decrypting 85 | $decrypted = $cryptor->decrypt($encrypted, $add); 86 | ``` 87 | 88 | If the `$add` differs, decryption will fail — ensuring data integrity. 89 | 90 | --- 91 | 92 | ## Security Design 93 | 94 | | Aspect | Detail | 95 | |--------|---------| 96 | | **Algorithm** | AES-256-GCM (Authenticated Encryption) | 97 | | **IV** | Generated securely via `random_bytes()` | 98 | | **Tag** | Auto-generated and verified internally | 99 | | **Key Derivation** | `hash('sha256', $raw, true)` ensures 32-byte AES key | 100 | | **Memory Safety** | Key wiped in destructor (`__destruct()`) | 101 | | **Serialization Protection** | `__sleep()` prevents exposing secrets | 102 | | **Debug Protection** | `__debugInfo()` hides the key during dumps | 103 | 104 | --- 105 | 106 | ## Error Handling 107 | 108 | | Error | Thrown when | 109 | |-------|--------------| 110 | | `RuntimeException` | No key found in environment | 111 | | `InvalidArgumentException` | Unsupported cipher name | 112 | | `false` return | Encryption/decryption failure | 113 | 114 | You can wrap encryption/decryption calls inside `try/catch` if desired: 115 | 116 | ```php 117 | try { 118 | $cryptor = new Cryptor(); 119 | $data = $cryptor->decrypt($input); 120 | } catch (RuntimeException $e) { 121 | echo $e->getMessage(); 122 | } 123 | ``` 124 | 125 | --- 126 | 127 | ## 🧰 Supported Ciphers 128 | 129 | | Cipher | Description | 130 | |---------|--------------| 131 | | `aes-256-gcm` | (Default) Modern authenticated encryption | 132 | | `aes-128-gcm` | Lightweight variant | 133 | | `aes-256-cbc` | Legacy compatibility mode (no authentication) | 134 | 135 | > GCM mode is recommended for all new applications. 136 | 137 | --- 138 | 139 | ## Example Output Format 140 | 141 | Encrypted data is a **Base64-encoded JSON** like this: 142 | 143 | ```json 144 | { 145 | "iv": "r7KfWkJcGlZcL7hYp6oJrQ==", 146 | "value": "J9PDpax7oMGJ6M4qYQ==", 147 | "cipher": "YWVzLTI1Ni1nY20=", 148 | "tag": "AQIDBAUGBwgJCgsMDQ==" 149 | } 150 | ``` 151 | 152 | Entire JSON is Base64 encoded again to make it safe for database or URL storage. 153 | 154 | --- 155 | 156 | ## Methods Summary 157 | 158 | | Method | Description | 159 | |--------|--------------| 160 | | `__construct(?string $key = null)` | Initialize with custom or env key | 161 | | `encrypt(string $data, ?string $cipher = null, string $add = '')` | Encrypt data | 162 | | `decrypt(string $data, string $add = '')` | Decrypt data | 163 | | `verify(string $plain, string $encrypted, string $add = '')` | Check if decrypted value matches plain text | 164 | 165 | --- 166 | 167 | ## Example Integration (with Laravel) 168 | 169 | ```php 170 | // config/app.php 171 | 'providers' => [ 172 | Lazervel\Cryptor\Cryptor::class, 173 | ], 174 | 175 | // usage 176 | $cryptor = app(Lazervel\Cryptor\Cryptor::class); 177 | $encrypted = $cryptor->encrypt('Secret Message'); 178 | ``` 179 | 180 | --- 181 | 182 | ## License 183 | 184 | This package is open-sourced software licensed under the **MIT License**. 185 | 186 | --- 187 | 188 | ## Author 189 | 190 | **Indian Modassir** 191 | Developer of [Lazervel](https://github.com/indianmodassir) — a collection of modern PHP libraries for secure, modular development. 192 | 193 | --- 194 | --------------------------------------------------------------------------------