Skip to content
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
/vendor/
/build/
/.idea/
composer.lock
composer.phar
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
php-openssl-cryptor
===================

Description
-----------
Simple to use class for encrypting/decrypting using the PHP Openssl library.
Simple to use class for encrypting/decrypting using the PHP Openssl library.

## Description

The Cryptor class supports arbitrary encryption and key hashing algorithms, along
with raw, base64 and hex encoding of the encrypted data. Static convenience methods
Expand All @@ -12,3 +12,29 @@ flexibility. The default uses aes-256-ctr to avoid the need for padding and the
issues. Unfortunately GCM cannot be used as the PHP openssl module does not provide
a way to retrieve the GCM tag. This is proposed to be remedied in PHP 7.1 when
associated data can be retrieved.

## Install

Require this library through composer:

```
composer require ioncube/php-openssl-cryptor
```


## Example

```php
use OpensslCryptor\Cryptor;

$data = 'Good things come in small packages.';
$key = '9901:io=[<>602vV03&Whb>9J&M~Oq';

$encrypted = Cryptor::Encrypt($data, $key);

echo "'$data' (" . strlen($data) . ") => '$encrypted'\n\n";

$decrypted = Cryptor::Decrypt($encrypted, $key);

echo "'$encrypted' => '$decrypted' (" . strlen($decrypted) . ")\n";
```
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"type": "library",
"license": "MIT",
"require": {
"php": ">=5.6",
"ext-openssl": "*"
},
"autoload": {
"psr-4": {
"ioncube\\phpOpensslCryptor\\": "src/"
"OpensslCryptor\\": "src/"
}
}
}
4 changes: 3 additions & 1 deletion examples/example.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use ioncube\phpOpensslCryptor\Cryptor;
require __DIR__ . '../vendor/autoload.php';

use OpensslCryptor\Cryptor;

$data = 'Good things come in small packages.';
$key = '9901:io=[<>602vV03&Whb>9J&M~Oq';
Expand Down
65 changes: 45 additions & 20 deletions src/Cryptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace ioncube\phpOpensslCryptor;
namespace OpensslCryptor;

use OpensslCryptor\Exception\ProcessException;
use OpensslCryptor\Exception\UnexpectedResultException;
use OpensslCryptor\Exception\UnknownAlgoException;

class Cryptor
{
Expand All @@ -38,35 +42,41 @@ class Cryptor

/**
* Construct a Cryptor, using aes256 encryption, sha256 key hashing and base64 encoding.
*
* @param string $cipher_algo The cipher algorithm.
* @param string $hash_algo Key hashing algorithm.
* @param [type] $fmt Format of the encrypted data.
* @param int $fmt Format of the encrypted data.
*
* @throws \Exception
*/
public function __construct($cipher_algo = 'aes-256-ctr', $hash_algo = 'sha256', $fmt = Cryptor::FORMAT_B64)
{
$this->cipher_algo = $cipher_algo;
$this->hash_algo = $hash_algo;
$this->format = $fmt;

if (!in_array($cipher_algo, openssl_get_cipher_methods(true)))
if (!in_array($cipher_algo, openssl_get_cipher_methods(true), false))
{
throw new \Exception("Cryptor:: - unknown cipher algo {$cipher_algo}");
throw new UnknownAlgoException('Unknown cipher algo ' . $cipher_algo);
}

if (!in_array($hash_algo, openssl_get_md_methods(true)))
if (!in_array($hash_algo, openssl_get_md_methods(true), false))
{
throw new \Exception("Cryptor:: - unknown hash algo {$hash_algo}");
throw new UnknownAlgoException('Unknown hash algo ' . $hash_algo);
}

$this->iv_num_bytes = openssl_cipher_iv_length($cipher_algo);
}

/**
* Encrypt a string.
*
* @param string $in String to encrypt.
* @param string $key Encryption key.
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
*
* @return string The encrypted string.
* @throws \Exception
*/
public function encryptString($in, $key, $fmt = null)
{
Expand All @@ -77,8 +87,15 @@ public function encryptString($in, $key, $fmt = null)

// Build an initialisation vector
$iv = openssl_random_pseudo_bytes($this->iv_num_bytes, $isStrongCrypto);
if (!$isStrongCrypto) {
throw new \Exception("Cryptor::encryptString() - Not a strong key");

// key is not strong enough
if ($isStrongCrypto === false) {
throw new UnexpectedResultException('Not a strong key');
}

// failure during initialisation
if ($iv === false) {
throw new UnexpectedResultException('Failure while initializing the pseudo-random string of bytes');
}

// Hash the key
Expand All @@ -90,18 +107,18 @@ public function encryptString($in, $key, $fmt = null)

if ($encrypted === false)
{
throw new \Exception('Cryptor::encryptString() - Encryption failed: ' . openssl_error_string());
throw new ProcessException('Encryption failed: ' . openssl_error_string());
}

// The result comprises the IV and encrypted data
$res = $iv . $encrypted;

// and format the result if required.
if ($fmt == Cryptor::FORMAT_B64)
if ($fmt === self::FORMAT_B64)
{
$res = base64_encode($res);
}
else if ($fmt == Cryptor::FORMAT_HEX)
else if ($fmt === self::FORMAT_HEX)
{
$res = unpack('H*', $res)[1];
}
Expand All @@ -111,10 +128,13 @@ public function encryptString($in, $key, $fmt = null)

/**
* Decrypt a string.
*
* @param string $in String to decrypt.
* @param string $key Decryption key.
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
*
* @return string The decrypted string.
* @throws \Exception
*/
public function decryptString($in, $key, $fmt = null)
{
Expand All @@ -126,20 +146,19 @@ public function decryptString($in, $key, $fmt = null)
$raw = $in;

// Restore the encrypted data if encoded
if ($fmt == Cryptor::FORMAT_B64)
if ($fmt === self::FORMAT_B64)
{
$raw = base64_decode($in);
}
else if ($fmt == Cryptor::FORMAT_HEX)
else if ($fmt === self::FORMAT_HEX)
{
$raw = pack('H*', $in);
}

// and do an integrity check on the size.
if (strlen($raw) < $this->iv_num_bytes)
{
throw new \Exception('Cryptor::decryptString() - ' .
'data length ' . strlen($raw) . " is less than iv length {$this->iv_num_bytes}");
throw new UnexpectedResultException('Data length ' . strlen($raw) . ' is less than iv length ' . $this->iv_num_bytes);
}

// Extract the initialisation vector and encrypted data
Expand All @@ -155,18 +174,21 @@ public function decryptString($in, $key, $fmt = null)

if ($res === false)
{
throw new \Exception('Cryptor::decryptString - decryption failed: ' . openssl_error_string());
throw new ProcessException('Decryption failed: ' . openssl_error_string());
}

return $res;
}

/**
* Static convenience method for encrypting.
*
* @param string $in String to encrypt.
* @param string $key Encryption key.
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
*
* @return string The encrypted string.
* @throws \Exception
*/
public static function Encrypt($in, $key, $fmt = null)
{
Expand All @@ -176,10 +198,13 @@ public static function Encrypt($in, $key, $fmt = null)

/**
* Static convenience method for decrypting.
*
* @param string $in String to decrypt.
* @param string $key Decryption key.
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
*
* @return string The decrypted string.
* @throws \Exception
*/
public static function Decrypt($in, $key, $fmt = null)
{
Expand Down
8 changes: 8 additions & 0 deletions src/Exception/ProcessException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace OpensslCryptor\Exception;

class ProcessException extends \Exception
{

}
8 changes: 8 additions & 0 deletions src/Exception/UnexpectedResultException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace OpensslCryptor\Exception;

class UnexpectedResultException extends \Exception
{

}
8 changes: 8 additions & 0 deletions src/Exception/UnknownAlgoException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace OpensslCryptor\Exception;

class UnknownAlgoException extends \Exception
{

}
4 changes: 3 additions & 1 deletion tests/BasicCryptTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use ioncube\phpOpensslCryptor\Cryptor;
require __DIR__ . '../vendor/autoload.php';

use OpensslCryptor\Cryptor;

$data = 'Good things come in small packages.';
$key = '9901:io=[<>602vV03&Whb>9J&M~Oq';
Expand Down