diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b5240fb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +# insert_final_newline = true +# Automatically add new line to end of all files on save. + +# Set all PHP to tab => space*4 +[*.php] +indent_style = space +indent_size = 4 diff --git a/README.md b/README.md index 1d9c461..bc233ec 100644 --- a/README.md +++ b/README.md @@ -15,22 +15,42 @@ Encrypts and decrypts data using PHP with OpenSSL `composer require martinusso/opencrypt` +## Tips + + - *$secretKey* should have been previously generated in a cryptographically safe way, like [openssl_random_pseudo_bytes](http://php.net/manual/en/function.openssl-random-pseudo-bytes.php). OpenCrypt has the static method `OpenCrypt::generateKey()` for this. + ## Usage ``` $password = "OpenCrypt"; +// Should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes $secretKey = 'SECRET_KEY'; -$secretIV = 'SECRET_IV'; -$openCrypt = new OpenCrypt($secretKey, $secretIV); +$iv = base64_decode('hEHLyH4Irwqvnl8uJpHrnQ=='); + +$openCrypt = new OpenCrypt($secretKey, $iv); +// encrypt $encryptedPassword = $openCrypt->encrypt($password); -// $encryptedPassword = 'RTZPSEUybDZLZy9lSzYwaHk1Y0gxZz09' +// $encryptedPassword = 'GWw3bqL7FqjmRs0yyIR/8A==' + +// decrypt later.... $decryptedPassword = $openCrypt->decrypt($encryptedPassword); // $decryptedPassword = 'OpenCrypt' ``` +### generate IV +``` +$iv = OpenCrypt::generateIV(); +``` + +### generate key +``` +$secretKey = OpenCrypt::generateKey(); +``` + + ## License This software is open source, licensed under the The MIT License (MIT). See [LICENSE](https://github.com/martinusso/opencrypt/blob/master/LICENSE) for details. diff --git a/phpunit.xml b/phpunit.xml index 7c54260..c56421e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,7 +8,7 @@ - src + src/OpenCrypt diff --git a/src/OpenCrypt/OpenCrypt.php b/src/OpenCrypt/OpenCrypt.php index 24bd56f..670e04c 100644 --- a/src/OpenCrypt/OpenCrypt.php +++ b/src/OpenCrypt/OpenCrypt.php @@ -4,27 +4,49 @@ class OpenCrypt { - private $encryptMethod = "AES-256-CBC"; + /** + * The cipher method. For a list of available cipher methods, use openssl_get_cipher_methods() + */ + const CIPHER_METHOD = "AES-256-CBC"; + + /** + * When OPENSSL_RAW_DATA is specified, the returned data is returned as-is. + */ + const OPTIONS = OPENSSL_RAW_DATA; + + /** + * The key + * + * Should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes + */ private $secretKey; - private $secretIV; + + /** + * IV - A non-NULL Initialization Vector. + * + * Encrypt method AES-256-CBC expects 16 bytes - else you will get a warning + */ + private $iv; public function __construct( string $secretKey, - string $secretIV + string $iv = null ) { - // hash $this->secretKey = hash('sha256', $secretKey); - // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning - $this->secretIV = substr(hash('sha256', $secretIV), 0, 16); + + if (empty($iv)) { + $iv = self::generateIV(); + } + $this->iv = $iv; } public function encrypt($value) { $output = openssl_encrypt( $value, - $this->encryptMethod, + self::CIPHER_METHOD, $this->secretKey, - 0, - $this->secretIV + self::OPTIONS, + $this->iv ); return base64_encode($output); } @@ -32,10 +54,39 @@ public function encrypt($value) { public function decrypt($value) { return openssl_decrypt( base64_decode($value), - $this->encryptMethod, + self::CIPHER_METHOD, $this->secretKey, - 0, - $this->secretIV + self::OPTIONS, + $this->iv ); } + + public function iv() + { + return $this->iv; + } + + /** + * Generate IV + * + * @return int Returns a string of pseudo-random bytes, with the number of bytes expected by the method AES-256-CBC + */ + public static function generateIV() + { + $ivNumBytes = openssl_cipher_iv_length(self::CIPHER_METHOD); + return openssl_random_pseudo_bytes($ivNumBytes); + } + + /** + * Generate a key + * + * @param int $length The length of the desired string of bytes. Must be a positive integer. + * + * @return int Returns the hexadecimal representation of a binary data + */ + public static function generateKey($length = 512) + { + $bytes = openssl_random_pseudo_bytes($length); + return bin2hex($bytes); + } } diff --git a/tests/OpenCryptTest.php b/tests/OpenCryptTest.php index 55d2ed5..471bc0d 100644 --- a/tests/OpenCryptTest.php +++ b/tests/OpenCryptTest.php @@ -8,14 +8,34 @@ final class OpenCryptTest extends \PHPUnit\Framework\TestCase { public function testCrypt() { + $secretKey = 'ec3a85570a2b2122ad835984ba12e91f'; + $iv = base64_decode('hEHLyH4Irwqvnl8uJpHrnQ=='); $password = "OpenCrypt"; - $openCrypt = new OpenCrypt('1', '2'); + $openCrypt = new OpenCrypt($secretKey, $iv); + $this->assertEquals($iv, $openCrypt->iv()); $encryptedPassword = $openCrypt->encrypt($password); - $this->assertEquals('RTZPSEUybDZLZy9lSzYwaHk1Y0gxZz09', $encryptedPassword); + + $this->assertEquals('QDWPv3lyx9LaKuxIgIXooA==', $encryptedPassword); $decryptedPassword = $openCrypt->decrypt($encryptedPassword); $this->assertEquals($password, $decryptedPassword); } + + public function testGeneratingIV() + { + $secretKey = 'ec3a85570a2b2122ad835984ba12e91f'; + $password = "OpenCrypt"; + + $openCrypt = new OpenCrypt($secretKey); + $iv = $openCrypt->iv(); + $this->assertEquals(16, strlen($iv)); + } + + public function testGenerateKey() + { + $key = OpenCrypt::generateKey(); + $this->assertEquals(1024, strlen($key)); + } }