Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php
use \Defuse\Crypto\Crypto;

require_once'autoload.php';

function showResults($type, $start, $end, $count)
Expand All @@ -9,7 +10,6 @@ function showResults($type, $start, $end, $count)
echo $type, ': ', $rate, ' calls/s', "\n";
}


// Note: By default, the runtime tests are "cached" and not re-executed for
// every call. To disable this, look at the RuntimeTest() function.

Expand Down
14 changes: 14 additions & 0 deletions doc/01-Formats.md
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____]`
101 changes: 101 additions & 0 deletions doc/02-Crypto.php.md
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`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now CTR.

* **Padding**: `PKCS#7`
Copy link
Owner

Choose a reason for hiding this comment

The 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()
Copy link
Owner

Choose a reason for hiding this comment

The 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
Copy link
Owner

Choose a reason for hiding this comment

The 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');
Copy link
Owner

Choose a reason for hiding this comment

The 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) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these might be in a different namespace now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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');
}
```
137 changes: 137 additions & 0 deletions doc/03-File.php.md
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');
}
```
4 changes: 4 additions & 0 deletions doc/README.md
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
Loading