Skip to content

Commit

Permalink
12.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mmeyer2k authored Jul 2, 2019
1 parent 90f5d9f commit 1092f27
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 49 deletions.
72 changes: 35 additions & 37 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@ jobs:
- image: circleci/php:7.1
steps:
- checkout
- restore_cache:
keys:
- source-php7.1-{{ .Branch }}-{{ .Revision }}
- source-php7.1-{{ .Branch }}-
- source-php7.1-
- run: composer require phpunit/phpunit infection/infection
- run: mkdir -p coverage
- run: php vendor/phpunit/phpunit/phpunit --coverage-html coverage
- run: php vendor/phpunit/phpunit/phpunit --coverage-html coverage --coverage-clover=coverage.clover
- run: php vendor/infection/infection/bin/infection
- run: php examples/support.php
- run: wget https://scrutinizer-ci.com/ocular.phar
- run: php ocular.phar code-coverage:upload --format=php-clover coverage.clover
- save_cache:
key: source-php7.1-{{ .Branch }}-{{ .Revision }}
paths:
- vendor
- store_artifacts:
path: coverage
- store_artifacts:
Expand All @@ -20,52 +31,39 @@ jobs:
- image: circleci/php:7.2
steps:
- checkout
- run: mkdir -p coverage
- run: composer require phpunit/phpunit infection/infection
- run: php vendor/phpunit/phpunit/phpunit --coverage-html coverage
- run: php vendor/infection/infection/bin/infection
- run: php examples/support.php
- store_artifacts:
path: coverage
- store_artifacts:
path: infection.log
- restore_cache:
keys:
- source-php7.2-{{ .Branch }}-{{ .Revision }}
- source-php7.2-{{ .Branch }}-
- source-php7.2-
- run: composer require phpunit/phpunit
- run: php vendor/phpunit/phpunit/phpunit
- save_cache:
key: source-php7.2-{{ .Branch }}-{{ .Revision }}
paths:
- vendor

build-73:
docker:
- image: circleci/php:7.3
steps:
- checkout
- run: mkdir -p coverage
- run: composer require phpunit/phpunit infection/infection
- run: php vendor/phpunit/phpunit/phpunit --coverage-html coverage
- run: php vendor/infection/infection/bin/infection
- run: php examples/support.php
- store_artifacts:
path: coverage
- store_artifacts:
path: infection.log

clover:
docker:
- image: circleci/php:7.1
steps:
- checkout
- restore_cache:
keys:
- source-php7.2-{{ .Branch }}-{{ .Revision }}
- source-php7.2-{{ .Branch }}-
- source-php7.2-
- run: composer require phpunit/phpunit
- run: php vendor/phpunit/phpunit/phpunit --coverage-clover=coverage.clover
- run: wget https://scrutinizer-ci.com/ocular.phar
- run: php ocular.phar code-coverage:upload --format=php-clover coverage.clover
- run: php vendor/phpunit/phpunit/phpunit
- save_cache:
key: source-php7.2-{{ .Branch }}-{{ .Revision }}
paths:
- vendor

workflows:
version: 2
build-test-all:
jobs:
- build
- build-72:
requires:
- build
- build-73:
requires:
- build-72
- clover:
requires:
- build-73
- build-72
- build-73
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ To generate a new key, execute this on the command line:
head -c 2048 /dev/urandom | base64 -w 0 | xargs echo
```

Storing this key safely is up to you!
Storing this key safely is up to you! [Guide to keys](https://github.com/mmeyer2k/dcrypt/blob/master/docs/KEYS.md).

[Specification document](https://github.com/mmeyer2k/dcrypt/blob/master/docs/CRYPTO.md)


### AES-256 GCM Encryption

Expand Down Expand Up @@ -163,16 +166,18 @@ try {
## Stream Ciphers

Be sure you understand the risks and inherent issues of using a stream cipher before proceeding.
Read the relevant information before using a stream cipher for anything important
Read the relevant information before using a stream cipher for anything important:

- [https://en.wikipedia.org/wiki/Stream_cipher_attacks](https://en.wikipedia.org/wiki/Stream_cipher_attacks)
- [https://jameshfisher.com/2018/01/01/making-a-stream-cipher/](https://jameshfisher.com/2018/01/01/making-a-stream-cipher/)

### One Time Pad

A fast symmetric stream cipher is quickly accessible with the `OneTimePad` class.
A novel counter-based stream cipher.
`OneTimePad` uses SHA3-512 to output a keystream that is ⊕'d with the input in 512 bit chunks.

[Specification document](https://github.com/mmeyer2k/dcrypt/blob/master/docs/ONETIMEPAD.md)

```php
<?php
$encrypted = \Dcrypt\OneTimePad::crypt('a secret', $key);
Expand Down
17 changes: 16 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changes in Dcrypt

## 12.0.1
- Much more efficient testing config
- Fix spelling mistakes
- Create a keys guide
- Add vendor caching to circle tests
- Add a ONETIMEPAD spec document

## 12.0.0
- Increase minimum key size to 2048 bytes
- Adds PHP 7.3 testing support to circle ci
Expand Down Expand Up @@ -83,4 +90,12 @@
- Cleaner calls to centralized hmac function
- Better internal API
- Dropped more PHP5 specific code
- Better code docs
- Better code docs

## 8.0.1
- Released 8.0.1 before merging PR

## 8.0.0
- `Aes` has been renamed to `AesCbc`.
- Many improvents to structure and readability
- Added normalized hmac wrapper
81 changes: 81 additions & 0 deletions docs/KEYS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Guide to dcrypt keys

Dcrypt likes __BIG__ keys.
This document explains some of the reasoning behind these design decisions and some tips on handling keys.

## Why 2048 bytes though?

At 2048 bytes the probability of any byte in the 0x00 to 0xFF range being used at least once approaches 1.
Unless, of course, a source of low entropy were to used for the initial keying material.

A basic test is performed at run time to indicate whether the key is likely to be pseudorandom.
An exception is raised if the key does not pass this test.
This test is not perfect but it is simple and fast.
It may become conditional in the future.

A generic of the randomness test is this as follows:

```php
<?php
if (\count(\array_unique(\str_split($key))) < 250) {
// throw exception
}
```

The large size of 2048 bytes safely allows us to forgo computationally wasteful and potentially dangerous password derivation while still providing strong security.

## Create a new key

Command line to screen:

```bash
head -c 2048 /dev/urandom | base64 -w 0 | xargs echo
```

Command line to file:

```bash
head -c 2048 /dev/urandom | base64 -w 0 > ~/secret.key
```

PHP static function:

```php
<?php

$key = \Dcrypt\OpensslKey::create();

file_put_contents("~/secret.key", $key);
```

## Storage tips

Since the key is base64 encoded it can contain any whitespace you desire.
An optimal solution when using opcache is to store as a single file and use it in a `require` statement.

```php
<?php

# content of /path/to/secret.key

return <<<EOT

key....................................................
key....................................................
key....................................................
key....................................................
key....................................................

EOT;

```

then...

```php
<?php

$key = require '/path/to/secret.key';
```

Keys can also be stored in environment files, functions, and class properties.
23 changes: 23 additions & 0 deletions docs/ONETIMEPAD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OneTimePad

A novel counter-based stream cipher.

# Definitions

- `DATA` data to encrypt or decrypt
- `KEY` to be given to key manager
- `ALGO` default sha3-512
- `COUNTER`
- `HKDF`
- algo
- key
- iv
- info
- `IV` __a blank string__
- `INFO` is the concatenation of `LENGTH` and index number of `CHUNK`

# Method of Encrypt and Decryption
1. Break `DATA` into an array (`CHUNKS`) of strings with a max width equal to the size of the hashing algo
1. Compute `LENGTH` where `LENGTH = strlen(DATA)`
1. For each `CHUNK` in `CHUNKS`, replace with `CHUNK = CHUNK ^ HKDF(ALGO, KEY, IV, INFO)`
1. Once all elements in `CHUNKS` have been processed then `implode` and `return`
2 changes: 1 addition & 1 deletion docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Dcrypt tests code in many different ways to ensure high quality and reliability.

## Vector testing
To ensure that backwards compatibility is maintained across versions, dcrypt tests functional output against the output of older versions.
Test vectors are stored in [tests/vectors](https://github.com/mmeyer2k/dcrypt/tree/master/tests/vectors)
Test vectors are stored in [tests/vectors](https://github.com/mmeyer2k/dcrypt/tree/master/tests/.vectors.json)

## Unit testing
Continuous unit testing on all supported PHP versions is performed using circle-ci with phpunit.
Expand Down
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions src/Exceptions/InvalidChecksumException.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<?php declare(strict_types=1);

/**
* InvalidChecksumException.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\Exceptions;

class InvalidChecksumException extends \Exception
Expand Down
12 changes: 12 additions & 0 deletions src/Exceptions/InvalidKeyException.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<?php declare(strict_types=1);

/**
* InvalidKeyException.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\Exceptions;

class InvalidKeyException extends \Exception
Expand Down
3 changes: 3 additions & 0 deletions src/OneTimePad.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public static function crypt(string $input, string $key, string $algo = 'sha3-51
$key = new OpensslKey($algo, $key, '');

foreach ($chunks as $i => &$chunk) {
// Create the info key based on counter
$info = $length . $i;

// Xor the derived key with the data chunk
$chunk = $chunk ^ $key->deriveKey($info);
}

Expand Down
10 changes: 4 additions & 6 deletions src/OpensslKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class OpensslKey
*
* @param string $algo Algo to use for HKDF
* @param string $key Key
* @param string $ivr Initialization vactor
* @param string $ivr Initialization vector
* @throws InvalidKeyException
*/
public function __construct(string $algo, string $key, string $ivr)
Expand All @@ -57,7 +57,7 @@ public function __construct(string $algo, string $key, string $ivr)

// Make sure key was properly decoded and meets minimum required length
if (!is_string($this->key) || Str::strlen($this->key) < 2048) {
throw new InvalidKeyException("Key must be at least 256 bytes and base64 encoded.");
throw new InvalidKeyException("Key must be at least 2048 bytes and base64 encoded.");
}

// Make sure key meets minimum entropy requirement
Expand Down Expand Up @@ -95,16 +95,14 @@ public function encryptionKey(string $info): string
}

/**
* Derive a key with differing authinfo strings
* Derive a key with differing info string parameters
*
* @param string $info Info parameter to provide to hash_hkdf
* @return string
*/
public function deriveKey(string $info): string
{
$key = \hash_hkdf($this->algo, $this->key, 0, $info, $this->ivr);

return $key;
return \hash_hkdf($this->algo, $this->key, 0, $info, $this->ivr);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/OpensslStatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static function decrypt(string $data, string $key, string $cipher, string

// Compare given checksum against computed checksum using a time-safe function
if (!Str::equal($chk, $sum)) {
throw new InvalidChecksumException('Decryption can not proceed due to invalid cyphertext checksum.');
throw new InvalidChecksumException('Decryption can not proceed due to invalid ciphertext checksum.');
}

// Decrypt message and return
Expand Down

0 comments on commit 1092f27

Please sign in to comment.