-
Notifications
You must be signed in to change notification settings - Fork 311
Proposed version 2.0 - file streaming, version tagging #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Cryptographic Message Formats | ||
|
|
||
| ## `\Defuse\Crypto\Crypto` | ||
|
|
||
| `[____VERSION____][____HMAC____][____HKDF_SALT____][____IV____][____CIPHERTEXT____]` | ||
|
|
||
|
|
||
| ### Legacy Encryption format (can only be decrypted with `legacyDecrypt()` | ||
|
|
||
| `[____HMAC____][____IV____][____CIPHERTEXT____]` | ||
|
|
||
| ## `\Defuse\Crypto\File` | ||
|
|
||
| `[____VERSION____][____HKDF_SALT____][____FIRST_NONCE____][____CIPHERTEXT____][____HMAC____]` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| Symmetric Key Encryption | ||
| ======================== | ||
|
|
||
| At a glance: | ||
|
|
||
| * **Cipher and Mode**: `AES-128-CBC` | ||
| * **Padding**: `PKCS#7` | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not used since CTR. |
||
| * **Authentication**: `HMAC-SHA-256` | ||
| * **Construction**: `Encrypt then MAC` | ||
| * **Algorithm Backend**: `ext/openssl` | ||
|
|
||
| ## `\Defuse\Crypto\Crypto` | ||
|
|
||
| **WARNING:** This encryption library is not a silver bullet. It only provides | ||
| symmetric encryption given a uniformly random key. This means you **MUST NOT** | ||
| use an ASCII string like a password as the key parameter, it **MUST** be | ||
| a uniformly random key generated by `createNewRandomKey()`. If you want to | ||
| encrypt something with a password, apply a password key derivation function | ||
| like PBKDF2 or scrypt with a random salt to generate a key. | ||
|
|
||
| ***WARNING:*** Error handling is *very* important, especially for crypto code! | ||
|
|
||
| How to use this code: | ||
| ===================== | ||
|
|
||
| Generating a Key | ||
| ---------------- | ||
|
|
||
| ```php | ||
| try { | ||
| $key = \Defuse\Crypto\Crypto::createNewRandomKey(); | ||
| // WARNING: Do NOT encode $key with bin2hex() or base64_encode(), | ||
| // they may leak the key to the attacker through side channels. | ||
| // | ||
| // This library offers these two for cache-timing-safe encoding: | ||
| // | ||
| // \Defuse\Crypto\Crypto\binToHex() | ||
| // \Defuse\Crypto\Crypto\hexToBin() | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome! |
||
| // | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely create a key'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely create a key'); | ||
| } | ||
| ``` | ||
|
|
||
| Encrypting a Message | ||
| -------------------- | ||
|
|
||
| ```php | ||
| $message = 'ATTACK AT DAWN'; | ||
| try { | ||
| $ciphertext = \Defuse\Crypto\Crypto::Encrypt($message, $key); | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } | ||
| ``` | ||
|
|
||
| Decrypting a Message | ||
| -------------------- | ||
|
|
||
| ```php | ||
| try { | ||
| $decrypted = self::Decrypt($ciphertext, $key); | ||
| } catch (\Defuse\Crypto\Exception\InvalidCiphertext $ex) { // VERY IMPORTANT | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This exception seems to be in a different namespace than the ones below, is it still correct? |
||
| // Either: | ||
| // 1. The ciphertext was modified by the attacker, | ||
| // 2. The key is wrong, or | ||
| // 3. $ciphertext is not a valid ciphertext or was corrupted. | ||
| // Assume the worst. | ||
| die('DANGER! DANGER! The ciphertext has been tampered with!'); | ||
| } catch (CryptoTestFailedException $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } catch (CannotPerformOperationException $ex) { | ||
| die('Cannot safely perform decryption'); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An important property to keep in mind: Tampering the ciphertext should only be able to lead to InvalidCiphertext exceptions, i.e. the attacker shouldn't be able to trick you into thinking the runtime test failed or something like that (just thinking out loud). |
||
| } | ||
| ``` | ||
|
|
||
|
|
||
|
|
||
| Decrypting a Message Encrypted with version 1 of this Library | ||
| ------------------------------------------------------------- | ||
|
|
||
| ```php | ||
| try { | ||
| $decrypted = self::legacyDecrypt($ciphertext, $key); | ||
| } catch (\Defuse\Crypto\Exception\InvalidCiphertext $ex) { // VERY IMPORTANT | ||
| // Either: | ||
| // 1. The ciphertext was modified by the attacker, | ||
| // 2. The key is wrong, or | ||
| // 3. $ciphertext is not a valid ciphertext or was corrupted. | ||
| // Assume the worst. | ||
| die('DANGER! DANGER! The ciphertext has been tampered with!'); | ||
| } catch (CryptoTestFailedException $ex) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these might be in a different namespace now?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! Good catch. |
||
| die('Cannot safely perform decryption'); | ||
| } catch (CannotPerformOperationException $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| Symmetric Key File Encryption | ||
| ============================= | ||
|
|
||
| At a glance: | ||
|
|
||
| * **Cipher and Mode**: `AES-128-CTR` | ||
| * **Padding**: None (CTR mode doesn't pad) | ||
| * **Authentication**: `HMAC-SHA-256` | ||
| * **Construction**: `Encrypt then MAC` | ||
| * **Algorithm Backend**: `ext/openssl` | ||
|
|
||
| ## `\Defuse\Crypto\File` | ||
|
|
||
| **WARNING:** This encryption library is not a silver bullet. It only provides | ||
| symmetric encryption given a uniformly random key. This means you **MUST NOT** | ||
| use an ASCII string like a password as the key parameter, it **MUST** be | ||
| a uniformly random key generated by `createNewRandomKey()`. If you want to | ||
| encrypt something with a password, apply a password key derivation function | ||
| like PBKDF2 or scrypt with a random salt to generate a key. | ||
|
|
||
| ***WARNING:*** Error handling is *very* important, especially for crypto code! | ||
|
|
||
| How to use this code: | ||
| ===================== | ||
|
|
||
| Generating a Key | ||
| ---------------- | ||
|
|
||
| ```php | ||
| try { | ||
| $key = \Defuse\Crypto\File::createNewRandomKey(); | ||
| // WARNING: Do NOT encode $key with bin2hex() or base64_encode(), | ||
| // they may leak the key to the attacker through side channels. | ||
| // | ||
| // This library offers these two for cache-timing-safe encoding: | ||
| // | ||
| // \Defuse\Crypto\File\binToHex() | ||
| // \Defuse\Crypto\File\hexToBin() | ||
| // | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely create a key'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely create a key'); | ||
| } | ||
| ``` | ||
|
|
||
| Encrypting a File | ||
| ----------------- | ||
|
|
||
| ```php | ||
| /* | ||
| // Don't forget to generate a random key | ||
| $key = \Defuse\Crypto\File::createNewRandomKey(); | ||
| */ | ||
|
|
||
| $inputFilename = 'image.jpg'; | ||
| $outputFilename = 'image.enc.jpg'; | ||
|
|
||
| try { | ||
| \Defuse\Crypto\File::encryptFile( | ||
| $inputFilename, | ||
| $outputFilename, | ||
| $key | ||
| ); | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } | ||
| ``` | ||
|
|
||
| Decrypting a File | ||
| ----------------- | ||
|
|
||
| ```php | ||
| /* | ||
| // Don't forget to generate a random key | ||
| $key = \Defuse\Crypto\File::createNewRandomKey(); | ||
| */ | ||
|
|
||
| $inputFilename = 'image.enc.jpg'; | ||
| $outputFilename = 'image.dec.jpg'; | ||
|
|
||
| try { | ||
| \Defuse\Crypto\File::decryptFile( | ||
| $inputFilename, | ||
| $outputFilename, | ||
| $key | ||
| ); | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } | ||
| ``` | ||
|
|
||
| Encrypting a File Resource | ||
| -------------------------- | ||
|
|
||
| ```php | ||
| /* | ||
| // Don't forget to generate a random key | ||
| $key = \Defuse\Crypto\File::createNewRandomKey(); | ||
| */ | ||
|
|
||
| $iFile = \fopen('image2.jpg', 'rb'); | ||
| $oFile = \fopen('image2.enc.jpg', 'wb'); | ||
|
|
||
| try { | ||
| \Defuse\Crypto\File::encryptResource($iFile, $oFile, $key); | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely perform encryption'); | ||
| } | ||
| ``` | ||
|
|
||
| Decrypting a File Resource | ||
| -------------------------- | ||
|
|
||
| ```php | ||
| /* | ||
| // Don't forget to generate a random key | ||
| $key = \Defuse\Crypto\File::createNewRandomKey(); | ||
| */ | ||
|
|
||
| $iFile = \fopen('image2.enc.jpg', 'rb'); | ||
| $oFile = \fopen('image2.dec.jpg', 'wb'); | ||
|
|
||
| try { | ||
| \Defuse\Crypto\File::decryptResource($iFile, $oFile, $key); | ||
| } catch (\Defuse\Crypto\Exception\CryptoTestFailed $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } catch (\Defuse\Crypto\Exception\CannotPerformOperation $ex) { | ||
| die('Cannot safely perform decryption'); | ||
| } | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # PHP Encryption Documentation | ||
|
|
||
| Web: https://defuse.ca/secure-php-encryption.htm | ||
| GitHub: https://github.com/defuse/php-encryption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now CTR.