Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Crecket committed Dec 28, 2015
1 parent 9029570 commit 50afefb
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/
phpunit.phar
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: php
php:
- "5.6"
script: phpunit tests/test.php
install:
- composer self-update
- composer update --prefer-dist
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,54 @@
# secure-functions
A collection of functions which can be used for security

## Instalation

#### Composer
Install through composer and require the autoloader.

`composer require crecket/secure-functions`

#### Manual
Download the files and require them in your project.

`require '/secure-functions/src/SecureFuncs.php';`



## Usage
All functions are static public functions right now so you can simply call the functions like this:

`SecureFuncs\SecureFuncs::password_hash('input');`


## Functions

### decrypt($input, $key)
Returns the decryped output as a string using [defuse/php-encryption](https://github.com/defuse/php-encryption)'s library.

### encrypt($input, $key = false)
Encrypt a string, if no key is given one will be generated for you (Recommended) using [defuse/php-encryption](https://github.com/defuse/php-encryption)'s library.

### password_hash($password)
Hash the given password. This function allows for longer passwords and isn't affected by the null-byte issue.

### password_verify($password, $hash)
Verify the given password hash

### randomHex($length)
Returns a random hexadecimal number for the given length

### randomInt($min, $max)
Returns the a secure random integer within the given range.

### randomSecureKey()
Return a random key using [defuse/php-encryption](https://github.com/defuse/php-encryption)'s library.

### randomString($length)
Returns a random string for the given length

### pseudoBytes($length)
Returns random bytes for the given length

### strlen($str)
Returns the length of the given string using mb_strlen when available
20 changes: 20 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "crecket/secure-functions",
"description": "Secure-functions makes it easier to secure functionality",
"license": "WTFPL",
"authors": [
{
"name": "Gregory Goijaerts",
"email": "crecketgaming@gmail.com"
}
],
"require": {
"php": ">=5.6.0",
"defuse/php-encryption": "^1.2"
},
"autoload": {
"psr-4": {
"SecureFuncs\\": "src/"
}
}
}
66 changes: 66 additions & 0 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

176 changes: 176 additions & 0 deletions src/SecureFuncs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?php
namespace SecureFuncs;

class SecureFuncs
{

public static $secret;

/**
* @param $input
* @param $key
* @return string
* @throws \CannotPerformOperationException
* @throws \InvalidCiphertextException
*/
public static function decrypt($input, $key)
{
try {
return \Crypto::decrypt($input, $key);
} catch (Ex\InvalidCiphertextException $ex) {
die('DANGER! DANGER! The ciphertext has been tampered with!');
} catch (Ex\CryptoTestFailedException $ex) {
die('Cannot safely perform decryption');
} catch (Ex\CannotPerformOperationException $ex) {
die('Cannot safely perform decryption');
}
}

/**
* @param $input
* @param bool $key
* @return array
* @throws CannotPerformOperationException
* @throws \CannotPerformOperationException
*/
public static function encrypt($input, $key = false)
{
if ($key === false || GenericFuncs::strlen($key) !== Crypto::KEY_BYTE_SIZE) {
$key = self::randomSecureKey();
}

try {
$ciphertext = \Crypto::encrypt($input, $key);
} catch (Ex\CryptoTestFailedException $ex) {
die('Cannot safely perform encryption');
} catch (Ex\CannotPerformOperationException $ex) {
die('Cannot safely perform encryption');
}

return array('Key' => $key, 'Encrypted' => $ciphertext);
}

/**
* @param $password -> password to hash
* @return bool|string
*/
public static function password_hash($password)
{
return password_hash(base64_encode(hash('sha256', $password, true)), PASSWORD_DEFAULT);
}

/**
* @param $password -> password to check
* @param $hash -> hash to check
* @return bool
*/
public static function password_verify($password, $hash)
{
return password_verify(base64_encode(hash('sha256', $password, true)), $hash);
}

/**
* @param int $length
* @return string
* @throws Exception
*/
public static function randomHex($length)
{
$bytes = \ceil($length / 2);
$hex = \bin2hex(self::pseudoBytes($bytes));
return $hex;
}

/**
* @param $min
* @param $max
* @return mixed
* @throws \Exception
*/
public static function randomInt($min, $max)
{
if ($max <= $min) {
throw new \Exception('Minimum equal or greater than maximum!');
}
if ($max < 0 || $min < 0) {
throw new \Exception('Only positive integers supported for now!');
}
$difference = $max - $min;
for ($power = 8; \pow(2, $power) < $difference; $power = $power * 2) ;
$powerExp = $power / 8;

do {
$randDiff = \hexdec(\bin2hex(self::pseudoBytes($powerExp)));
} while ($randDiff > $difference);
return $min + $randDiff;
}

/**
* @return string
*/
public static function randomSecureKey()
{
try {
return \Crypto::createNewRandomKey();
} catch (Ex\CryptoTestFailedException $ex) {
die('Cannot safely create a key');
} catch (Ex\CannotPerformOperationException $ex) {
die('Cannot safely create a key');
}
}

/**
* @param $length
* @return string
* @throws Exception
*/
public static function randomString($length)
{

$charactersArr = \array_merge(\range('a', 'z'), \range('A', 'Z'), \range('0', '9'));

$charactersCount = \count($charactersArr);

$stringArr = array();

for ($character = 0; $character !== $length; $character++) {
$stringArr[$character] = $charactersArr[self::randomInt(0, $charactersCount - 1)];
}

return \implode($stringArr);
}

/**
* @param int $length
* @return string
* @throws \Exception
*/
public static function pseudoBytes($length = 1)
{
$bytes = openssl_random_pseudo_bytes($length, $strong);
if ($strong === TRUE) {
return $bytes;
} else {
throw new \Exception ('Insecure server! (OpenSSL Random byte generation insecure.)');
}
}

/**
* @param $str
* @return int
* @throws CannotPerformOperationException
*/
public static function strlen($str)
{
if (function_exists('mb_strlen')) {
$length = mb_strlen($str, '8bit');
if ($length === FALSE) {
throw new CannotPerformOperationException();
}
return $length;
} else {
return strlen($str);
}
}

}
58 changes: 58 additions & 0 deletions tests/test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
require __DIR__ . '/../vendor/autoload.php';

class test extends PHPUnit_Framework_TestCase
{

public function testEncryptDecrypt()
{

$message = "1234567890abcdefghijklmnopqrstuvwxyz";
$encryptedData = SecureFuncs\SecureFuncs::encrypt($message);

$this->assertArrayHasKey('Key', $encryptedData);

$this->assertNotEmpty($encryptedData['Key']);

$this->assertArrayHasKey('Encrypted', $encryptedData);

$this->assertNotEmpty($encryptedData['Encrypted']);

$decryptedText = SecureFuncs\SecureFuncs::decrypt($encryptedData['Encrypted'], $encryptedData['Key']);

$this->assertEquals($message, $decryptedText);

}

public function testRandom()
{

$this->assertNotEmpty(\SecureFuncs\SecureFuncs::pseudoBytes(32));

$this->assertStringMatchesFormat('%s', \SecureFuncs\SecureFuncs::randomHex(32));

$this->assertStringMatchesFormat('%s', \SecureFuncs\SecureFuncs::randomString(32));

$this->assertInternalType('int', \SecureFuncs\SecureFuncs::randomInt(32, 64));

}

public function testPassword()
{

$password = "qwerty1234567";

$hash = \SecureFuncs\SecureFuncs::password_hash($password);

$this->assertInternalType('string', $hash);

$this->assertTrue(\SecureFuncs\SecureFuncs::password_verify($password, $hash));

}

public function testOther()
{
$this->assertEquals(9, \SecureFuncs\SecureFuncs::strlen('123456789'));
}

}

0 comments on commit 50afefb

Please sign in to comment.