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));
+ }
}