Skip to content

Commit

Permalink
8.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mmeyer2k authored Jul 13, 2018
1 parent 750179b commit 0c950e8
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 196 deletions.
3 changes: 0 additions & 3 deletions .gitignore

This file was deleted.

70 changes: 54 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
[![Latest Stable Version](https://poser.pugx.org/mmeyer2k/dcrypt/version)](https://packagist.org/packages/mmeyer2k/dcrypt)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/c48adefc-874e-4d14-88dc-05f7f407f968/mini.png)](https://insight.sensiolabs.com/projects/c48adefc-874e-4d14-88dc-05f7f407f968)

A petite library of essential encryption functions for PHP7. For PHP5 support, check out the legacy branch [here](https://github.com/mmeyer2k/dcrypt/tree/4.0.2).
A petite library of essential encryption functions for PHP7.
For PHP5 support, check out the legacy branch [here](https://github.com/mmeyer2k/dcrypt/tree/4.0.2).

- [Install](#install)
- [Features](#features)
Expand All @@ -19,11 +20,11 @@ A petite library of essential encryption functions for PHP7. For PHP5 support, c
- [Key Derivation Function](#key-derivation-function)
- [Time-safe String Comparison](#time-safe-string-comparison)
- [Usage Notes](#usage-notes)
- [API Documentation](#api-documentation)
- [Show me some love](#show-me-some-love-heart_eyes) :heart_eyes:

# Install
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=~8.0"
```
Expand All @@ -36,7 +37,9 @@ require 'path/to/dcrypt/load.php';
## Block Ciphers

### AES-256-CBC Encryption
Quickly access AES-256-CBC encryption with `\Dcrypt\AesCbc`. All of the most secure options are the default. Naturally, strongly random initialization vectors are generated upon encryption and standard HMAC (SHA-256) checksums are verified in a time-safe manner before decryption.
Quickly access AES-256-CBC encryption with `\Dcrypt\AesCbc`.
All of the most secure options are the default.
Naturally, strongly random initialization vectors are generated upon encryption and standard HMAC (SHA-256) checksums are verified in a time-safe manner before decryption.
```php
$encrypted = \Dcrypt\AesCbc::encrypt($plaintext, $password);

Expand All @@ -51,9 +54,42 @@ $encrypted = \Dcrypt\AesCtr::encrypt($plaintext, $password);
$plaintext = \Dcrypt\AesCtr::decrypt($encrypted, $password);
```
[Definitive StackExchange thread on CBC vs CTR](https://security.stackexchange.com/questions/27776/block-chaining-modes-to-avoid/27780#27780)

### Custom Encryption Suites
`dcrypt`'s internal functions are easily extendable by overloading the `OpensslBridge` class.
Use `openssl_get_cipher_method()` and `hash_algos()` to gather available options.

```php
<?php

/**
* Use blowfish64 + crc32 to create smaller output sizes.
* This is useful for medium security situations where minimal space consumption is important.
*/
class TinyFish extends \Dcrypt\OpensslBridge
{
/**
* Specify using blowfish ofb cipher method
*
* @var string
*/
const CIPHER = 'bf-ofb';

/**
* Use crc32 hashing algo to authenticate messages
*
* @var string
*/
const CHKSUM = 'crc32';
}
```

**NOTE**:
Only `\Dcrypt\AesCbc` and `\Dcrypt\AesCtr` are tested by this library. If you roll your own, write some tests!

### Iterative HMAC Key Hardening
To reduce the effectiveness of brute-force cracking on your encrypted blobs, you can provide an integer `$cost` parameter
in your encryption/decryption calls. This integer will cause dcrypt to perform `$cost` number of extra HMAC operations on the key before passing it off to the underlying encryption system.
To reduce the effectiveness of brute-force cracking on your encrypted blobs, you can provide an integer `$cost` parameter in your encryption/decryption calls.
This integer will cause dcrypt to perform `$cost` number of extra HMAC operations on the key before passing it off to the underlying encryption system.
```php
$encrypted = \Dcrypt\AesCbc::encrypt($plaintext, $password, 10000);

Expand Down Expand Up @@ -103,10 +139,15 @@ $encrypted = \Dcrypt\Spritz::crypt($plaintext, $password);
$plaintext = \Dcrypt\Spritz::crypt($encrypted, $password);
```

**NOTE**: These implementations are for reference only. The RC4 cipher in general has many known security problems, and the Spirtz implementation provided here has not been verified against known test vectors.
Both are very slow and inefficient. This was just for fun. Use block ciphers for anything important.
**NOTE**:
These implementations are for reference only.
The RC4 cipher in general has many known security problems, and the Spirtz implementation provided here has not been verified against known test vectors.
Both are very slow and inefficient.
This was just for fun.
Use block ciphers for anything important.

**NOTE**: Backwards compatibility breaking changes to these classes will not result in an incremented major version number.
**NOTE**:
Backwards compatibility breaking changes to these classes will not result in an incremented major version number.

## PKCS #7 Padding
PKCS#7 style padding is available via the `Pkcs7::pad()` and `Pkcs7::unpad()` functions.
Expand All @@ -123,10 +164,9 @@ PKCS#7 style padding is available via the `Pkcs7::pad()` and `Pkcs7::unpad()` fu
```

## Key Derivation Function
`Dcrypt\Hash` is an opaque 512 bit iterative hash function. First, SHA-256 is
used to hash a 16 byte initialization vector with your secret password to create
a unique key. Then `$cost` number of HMAC iterations are performed on the input
using the unique key.
`Dcrypt\Hash` is an opaque 512 bit iterative hash function.
First, SHA-256 is used to hash a 16 byte initialization vector with your secret password to create a unique key.
Then `$cost` number of HMAC iterations are performed on the input using the unique key.

The `$cost` parameter can be any integer between 0 and 2<sup>32</sup> - 1. This
`$cost` value is stored as 4 encrypted bytes in the output. A `$cost` value of
Expand Down Expand Up @@ -154,11 +194,9 @@ $equals = \Dcrypt\Str::equal('known', 'given');
1. The output size of `AesCbc::encrypt` on a 10 byte plaintext would be: IV (16 bytes) + SHA-256 HMAC (32 bytes) + encrypted plaintext and padding bytes (16 bytes) = 64 bytes.
1. Dcrypt is built entirely with static functions. If you are using the `new` keyword on any Dcrypt classes, you are doing it wrong!

# API Documentation
The latest API documentation can be found [here](https://mmeyer2k.github.io/dcrypt/).

# Show me some love :heart_eyes:
Developing dcrypt has been a labor of love for many years. If you find dcrypt useful, please consider donating some Litecoin to `LN97LrLCNiv14V6fntp247H2pj9UiFzUQZ`.
Developing dcrypt has been a labor of love for many years.
If you find dcrypt useful, please consider donating some Litecoin to `LN97LrLCNiv14V6fntp247H2pj9UiFzUQZ`.

![litecoin address](https://rawgit.com/mmeyer2k/dcrypt/master/litecoin.png)

Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"php": ">=7.0.0"
},
"require-dev": {
"mmeyer2k/retro": "dev-master"
},
"autoload": {
"psr-4": {
Expand Down
4 changes: 2 additions & 2 deletions load.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

// Source files must be in correct order to honor inheritance
$files = array(
'OpenSSL',
'OpensslWrapper',
'OpensslBridge',
'Str',
'Aes',
'Hash',
'AesCbc',
'AesCtr',
Expand Down
115 changes: 0 additions & 115 deletions src/Aes.php

This file was deleted.

59 changes: 4 additions & 55 deletions src/AesCbc.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @link https://github.com/mmeyer2k/dcrypt
* @link https://apigen.ci/github/mmeyer2k/dcrypt/namespace-Dcrypt.html
*/
class AesCbc extends Aes
class AesCbc extends OpensslBridge
{
/**
* AES-256 cipher identifier that will be passed to openssl
Expand All @@ -34,60 +34,9 @@ class AesCbc extends Aes
const CIPHER = 'aes-256-cbc';

/**
* Decrypt cyphertext
* Specify sha256 for message authentication
*
* @param string $data Cyphertext to decrypt
* @param string $pass Password that should be used to decrypt input data
* @param int $cost Number of extra HMAC iterations to perform on key
* @return string
*/
public static function decrypt(string $data, string $pass, int $cost = 0): string
{
// Find the IV at the beginning of the cypher text
$ivr = Str::substr($data, 0, static::IVSIZE);

// Gather the checksum portion of the ciphertext
$sum = Str::substr($data, static::IVSIZE, static::CKSIZE);

// Gather message portion of ciphertext after iv and checksum
$msg = Str::substr($data, static::IVSIZE + static::CKSIZE);

// Derive key from password
$key = static::key($pass, $ivr, $cost, static::mode());

// Calculate verification checksum
$chk = static::checksum($msg, $ivr, $key, static::mode());

// Verify HMAC before decrypting
static::checksumVerify($chk, $sum);

// Decrypt message and return
return static::opensslDecrypt($msg, static::CIPHER, $key, $ivr);
}

/**
* Encrypt plaintext
*
* @param string $data Plaintext string to encrypt.
* @param string $pass Password used to encrypt data.
* @param int $cost Number of extra HMAC iterations to perform on key
* @return string
* @var string
*/
public static function encrypt(string $data, string $pass, int $cost = 0): string
{
// Generate IV of appropriate size.
$ivr = \random_bytes(static::IVSIZE);

// Derive key from password
$key = self::key($pass, $ivr, $cost, static::mode());

// Encrypt the plaintext
$msg = static::opensslEncrypt($data, static::CIPHER, $key, $ivr);

// Create the cypher text prefix (iv + checksum)
$pre = $ivr . static::checksum($msg, $ivr, $key, static::mode());

// Return prefix + cyphertext
return $pre . $msg;
}
const CHKSUM = 'sha256';
}
Loading

0 comments on commit 0c950e8

Please sign in to comment.