Skip to content

Commit

Permalink
13.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mmeyer2k committed Jul 4, 2019
1 parent 42efb57 commit 82e58a0
Show file tree
Hide file tree
Showing 18 changed files with 280 additions and 159 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Add dcrypt to your composer.json file requirements.
Don't worry, dcrypt does not have any dependencies of its own.

```bash
composer require "mmeyer2k/dcrypt=^12.0"
composer require "mmeyer2k/dcrypt=^13.0"
```

# Features
Expand Down Expand Up @@ -76,13 +76,15 @@ If you read to this point then you are an experienced cryptonaut, congrats! :ok_

Several AES-256 encryption modes are supported out of the box via hardcoded classes.

| Class Name | OpenSSL Cipher | Further Reading |
| -------------------- | :--------------: | --------------- |
| `\Dcrypt\Aes256Gcm` | `aes-256-gcm` | [wiki](https://en.wikipedia.org/wiki/Galois/Counter_Mode) |
| `\Dcrypt\Aes256Cbc` | `aes-256-cbc` | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) |
| `\Dcrypt\Aes256Ctr` | `aes-256-ctr` | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)) |
| `\Dcrypt\Aes256Ofb` | `aes-256-ofb` | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_(OFB)) |
| `\Dcrypt\Aes256Ecb` | `aes-256-ecb` | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#ECB) |
| Class Name | OpenSSL Cipher | Security Rating | Further Reading |
| -------------------- | :--------------: | :---------------: | --------------- |
| `\Dcrypt\Aes256Gcm` | `aes-256-gcm` | :smiley: | [wiki](https://en.wikipedia.org/wiki/Galois/Counter_Mode) |
| `\Dcrypt\Aes256Ctr` | `aes-256-ctr` | :relaxed: | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)) |
| `\Dcrypt\Aes256Cbc` | `aes-256-cbc` | :expressionless: | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) |
| `\Dcrypt\Aes256Ofb` | `aes-256-ofb` | :grimacing: | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_(OFB)) |
| `\Dcrypt\Aes256Cfb` | `aes-256-cfb` | :hushed: | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_(CFB)) |
| `\Dcrypt\Aes256Ccm` | `aes-256-ccm` | :astonished: | [wiki](https://en.wikipedia.org/wiki/CCM_mode) |
| `\Dcrypt\Aes256Ecb` | `aes-256-ecb` | :rage: | [wiki](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#ECB) |

### Custom Encryption Suites

Expand Down
5 changes: 5 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes in Dcrypt

## 13.0.0
- Skip validating key when decrypting
- Clean up internal API
- Increase default AAD tag size

## 12.0.2
- More clarity and unity in internal API
- Add codesniffer to circle ci testing
Expand Down
3 changes: 3 additions & 0 deletions docs/UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Upgrade from 12.x to 13.x
- Anything encrypted with GCM or CCM will not be decryptable anymore due to change in tag sizes

# Upgrade from 11.x to 12.x
- Upgrade to minimum 2048 byte keys
- Rename `Otp` to `OneTimePad`
Expand Down
14 changes: 10 additions & 4 deletions examples/vectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@

require __DIR__ . '/../vendor/autoload.php';

$key = \Dcrypt\OpensslKey::create();
$vectors = __DIR__ . '/../tests/.vectors.json';

file_put_contents(__DIR__ . '/../tests/vectors/.testkey', $key);
if (file_exists($vectors)) {
$key = json_decode(file_get_contents($vectors))->key;
} else {
$key = \Dcrypt\OpensslKey::create();
}

$out = [
'key' => $key,
Expand Down Expand Up @@ -40,7 +44,7 @@
$out['algos'][$algo] = base64_encode(OpensslStatic::encrypt('a secret', $key, 'aes-256-gcm', $algo));
}

foreach(['Gcm', 'Ctr', 'Ofb', 'Cbc', 'Ecb'] as $mode){
foreach(['Gcm', 'Ctr', 'Ofb', 'Cbc', 'Ecb', 'Ccm', 'Cfb'] as $mode){
$c = "\\Dcrypt\\Aes256$mode";
$out['aes256'][$c] = base64_encode($c::encrypt('a secret', $key));
}
Expand All @@ -51,4 +55,6 @@
$out['otp'][$mult] = \base64_encode(\Dcrypt\OneTimePad::crypt(str_repeat('A', $mult), $key));
}

file_put_contents(__DIR__ . '/../tests/.vectors.json', \json_encode($out, JSON_PRETTY_PRINT));
file_put_contents(__DIR__ . '/../tests/.vectors.json', \json_encode($out, JSON_PRETTY_PRINT));

var_dump($out);
2 changes: 1 addition & 1 deletion src/Aes256Cbc.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Dcrypt;

/**
* Symmetric AES-256-GCM encryption functions powered by OpenSSL.
* Symmetric AES-256 GCM encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
Expand Down
34 changes: 34 additions & 0 deletions src/Aes256Ccm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

/**
* Aes256Ccm.php
*
* PHP version 7
*
* @category Dcrypt
* @package Dcrypt
* @author Michael Meyer (mmeyer2k) <m.meyer2k@gmail.com>
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
* @link https://github.com/mmeyer2k/dcrypt
*/

namespace Dcrypt;

/**
* Symmetric AES-256 CCM encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
* @author Michael Meyer (mmeyer2k) <m.meyer2k@gmail.com>
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
* @link https://github.com/mmeyer2k/dcrypt
*/
class Aes256Ccm extends Aes256Gcm
{
/**
* AES-256 cipher identifier that will be passed to openssl
*
* @var string
*/
const CIPHER = 'aes-256-ccm';
}
34 changes: 34 additions & 0 deletions src/Aes256Cfb.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

/**
* Aes256Cfb.php
*
* PHP version 7
*
* @category Dcrypt
* @package Dcrypt
* @author Michael Meyer (mmeyer2k) <m.meyer2k@gmail.com>
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
* @link https://github.com/mmeyer2k/dcrypt
*/

namespace Dcrypt;

/**
* Symmetric AES-256 CFB encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
* @author Michael Meyer (mmeyer2k) <m.meyer2k@gmail.com>
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
* @link https://github.com/mmeyer2k/dcrypt
*/
class Aes256Cfb extends Aes256Gcm
{
/**
* AES-256 cipher identifier that will be passed to openssl
*
* @var string
*/
const CIPHER = 'aes-256-cfb';
}
2 changes: 1 addition & 1 deletion src/Aes256Ctr.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Dcrypt;

/**
* Symmetric AES-256-CTR encryption functions powered by OpenSSL.
* Symmetric AES-256 CTR encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
Expand Down
2 changes: 1 addition & 1 deletion src/Aes256Ecb.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Dcrypt;

/**
* Symmetric AES-256-ECB encryption functions powered by OpenSSL.
* Symmetric AES-256 ECB encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
Expand Down
2 changes: 1 addition & 1 deletion src/Aes256Gcm.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Dcrypt;

/**
* Symmetric AES-256-GCM encryption functions powered by OpenSSL.
* Symmetric AES-256 GCM encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
Expand Down
2 changes: 1 addition & 1 deletion src/Aes256Ofb.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Dcrypt;

/**
* Symmetric AES-256-GCM encryption functions powered by OpenSSL.
* Symmetric AES-256 GCM encryption functions powered by OpenSSL.
*
* @category Dcrypt
* @package Dcrypt
Expand Down
2 changes: 1 addition & 1 deletion src/OneTimePad.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static function crypt(
$length = Str::strlen($input);

// Create a new key object
$key = new OpensslKey($algo, $key, '');
$key = new OpensslKey($algo, $key);

foreach ($chunks as $i => &$chunk) {
// Create the info key based on counter
Expand Down
45 changes: 32 additions & 13 deletions src/OpensslKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,32 @@ final class OpensslKey
/**
* OpensslKey constructor.
*
* @param string $algo Algo to use for HKDF
* @param string $key Key
* @param string $ivr Initialization vector
* @param string $algo Algo to use for HKDF
* @param string $key Key
* @param string $ivr Initialization vector
* @param bool $testKey Validate the key
*
* @throws InvalidKeyException
*/
public function __construct(string $algo, string $key, string $ivr)
{
public function __construct(
string $algo,
string $key,
string $ivr = '',
bool $testKey = true
) {
// Store the key as what was supplied
$this->_key = \base64_decode($key);

// Make sure key was properly decoded and meets minimum required length
if (!is_string($this->_key) || Str::strlen($this->_key) < 2048) {
throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
}
if ($testKey) {
// Make sure key was properly decoded and meets minimum required length
if (!is_string($this->_key) || Str::strlen($this->_key) < 2048) {
throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
}

// Make sure key meets minimum entropy requirement
if (\count(\array_unique(\str_split($this->_key))) < 250) {
throw new InvalidKeyException(InvalidKeyException::KEYRANDOM);
// Make sure key meets minimum entropy requirement
if (self::_testKeyEntropy($this->_key) === false) {
throw new InvalidKeyException(InvalidKeyException::KEYRANDOM);
}
}

// Store algo in object
Expand Down Expand Up @@ -126,9 +133,21 @@ public function deriveKey(string $info): string
public static function create(int $bytes = 2048): string
{
if ($bytes < 2048) {
throw new InvalidKeyException('Keys must be at least 2048 bytes long.');
throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
}

return \base64_encode(\random_bytes($bytes));
}

/**
* Returns true if key has enough entropy
*
* @param string $key Key string to test
*
* @return bool
*/
private static function _testKeyEntropy(string $key): bool
{
return \count(\array_unique(\str_split($key))) > 250;
}
}
4 changes: 2 additions & 2 deletions src/OpensslStatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static function decrypt(
$hsz = Str::hashSize($algo);

// Get the tag size in bytes for this cipher mode
$tsz = parent::tagRequired($cipher) ? 4 : 0;
$tsz = parent::tagRequired($cipher) ? 16 : 0;

// Ask openssl for the IV size needed for specified cipher
$isz = parent::ivSize($cipher);
Expand All @@ -66,7 +66,7 @@ public static function decrypt(
$msg = Str::substr($data, $isz + $hsz + $tsz);

// Create a new password derivation object
$key = new OpensslKey($algo, $key, $ivr);
$key = new OpensslKey($algo, $key, $ivr, false);

// Calculate checksum of message payload for verification
$chk = \hash_hmac($algo, $msg, $key->authenticationKey($cipher), true);
Expand Down
2 changes: 1 addition & 1 deletion src/OpensslWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected static function opensslEncrypt(
string &$tag
): string {
if (OpensslStatic::tagRequired($cipher)) {
return \openssl_encrypt($data, $cipher, $key, 1, $iv, $tag, '', 4);
return \openssl_encrypt($data, $cipher, $key, 1, $iv, $tag, '', 16);
} else {
return \openssl_encrypt($data, $cipher, $key, 1, $iv);
}
Expand Down
Loading

0 comments on commit 82e58a0

Please sign in to comment.