Skip to content

Commit

Permalink
fix: setKey uses sha256 hash and encrypt method updated
Browse files Browse the repository at this point in the history
  • Loading branch information
davodm committed Aug 4, 2024
1 parent dc648b4 commit c0acaef
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 26 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ use Dgcrypt\Dgcrypt;
// Initialize the Dgcrypt class with the desired encryption method
$dgcrypt = new Dgcrypt('aes-256-gcm'); // Can be 'aes-256-cbc', 'aes-256-gcm', or 'chacha20-poly1305'

// Set a 32-character secret key
$dgcrypt->setKey('your-32-character-long-key');
// Set a secret key
$dgcrypt->setKey('your-secret key');
```

### Encrypting Data on the Backend:
Expand All @@ -50,7 +50,7 @@ echo $encrypted;
### Decrypting Data on the Backend:
```php
// Decrypt the previously encrypted string
$decrypted = $dgcrypt->decrypt($encrypted);
$decrypted = $dgcrypt->setCipherMethod('aes-256-cbc')->decrypt($encrypted);

// Output the decrypted string
echo $decrypted;
Expand All @@ -62,7 +62,7 @@ echo $decrypted;
$generatedKey = $dgcrypt->generateKey();

// Output the generated key
echo bin2hex($generatedKey); // Display the key in hexadecimal format
echo $generatedKey; // Display the hexadecimal key
```

### Setting the Initialization Vector (IV):
Expand Down
50 changes: 30 additions & 20 deletions src/Dgcrypt.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,26 @@ public function __construct(string $cipherMethod = 'aes-256-cbc')
}

/**
* Sets the secret key for encryption and decryption.
* Sets the secret key for encryption and decryption based on sha256 hash.
* Always 32 characters long.
*
* @param string $key The secret key (must be 32 characters)
* @param string $key
* @return $this
* @throws \Exception if the key length is not 32 characters
*/
public function setKey(string $key)
{
if (strlen($key) !== 32) {
throw new \Exception('Secret key should be 32 characters');
}
$this->key = $key;
$this->key = substr(hash('sha256', $key),0,32);
return $this;
}

/**
* Auto-generates a secure random key.
* Auto-generates a secure random key that is 32 characters long.
*
* @return string The generated key
*/
public function generateKey()
{
$this->key = openssl_random_pseudo_bytes(32);
$this->setKey(openssl_random_pseudo_bytes(32));
return $this->key;
}

Expand All @@ -69,7 +66,7 @@ public function setIV(string $iv = null)
$this->iv = openssl_random_pseudo_bytes($ivLength);
} else {
if (strlen($iv) !== $ivLength) {
throw new \Exception("IV should be $ivLength bytes");
throw new \Exception('IV length should be ' . $ivLength . ' bytes for ' . $this->cipherMethod);
}
$this->iv = $iv;
}
Expand Down Expand Up @@ -102,7 +99,7 @@ public function setCipherMethod(string $method)
* @return string The encrypted string, base64 encoded
* @throws \Exception if the secret key is not defined or encryption fails
*/
public function encrypt(string $string, string $secretKey = null, bool $resetIV = false)
public function encrypt(string $string, string $secretKey = null, bool $resetIV = true)
{
if (!empty($secretKey)) {
$this->setKey($secretKey);
Expand Down Expand Up @@ -142,15 +139,23 @@ public function encrypt(string $string, string $secretKey = null, bool $resetIV
}

if ($encryptedString === false) {
throw new \Exception('Encryption failed');
throw new \Exception('Encryption failed: ' . openssl_error_string());
}

// Base 64 encode the encrypted string
$encryptedString = base64_encode(bin2hex($encryptedString));
// Convert tag to hex
if (!empty($tag)) {
$tag = bin2hex($tag);
}

// Add IV and tag to the encrypted string
$encryptedString = base64_encode(bin2hex($this->iv) . $tag . $encryptedString);

if ($resetIV) {
$this->iv = null;
}

$encryptedString = base64_encode($this->iv . $tag . $encryptedString);

return $encryptedString;
}

Expand All @@ -169,7 +174,7 @@ public function decrypt(string $string, string $secretKey = null)
} elseif (empty($this->key)) {
throw new \Exception('Key for decrypting is not defined');
}

// First Base64 decode the encrypted string
$decodedString = base64_decode($string);
if ($decodedString === false) {
throw new \Exception('Encoded string is manipulated or corrupted');
Expand All @@ -178,11 +183,16 @@ public function decrypt(string $string, string $secretKey = null)
$ivLength = openssl_cipher_iv_length($this->cipherMethod);
$tagLength = ($this->cipherMethod === 'aes-256-gcm' || $this->cipherMethod === 'chacha20-poly1305') ? 16 : 0;

$tag=($tagLength > 0) ? substr($decodedString, $ivLength, $tagLength) : null;
$iv = substr($decodedString, 0, $ivLength);
$encryptedData = substr($decodedString, $ivLength + $tagLength);
// Extract IV and tag from the decoded string
$iv = hex2bin(substr($decodedString, 0, $ivLength * 2)); // hex string is twice the length of binary
$tag = ($tagLength > 0) ? hex2bin(substr($decodedString, $ivLength * 2, $tagLength * 2)) : null;

$encryptedData = substr($decodedString, ($ivLength + $tagLength) * 2);

switch($this->cipherMethod) {
// Second Base64 decode the encrypted data
$encryptedData = hex2bin(base64_decode($encryptedData));

switch ($this->cipherMethod) {
case 'aes-256-cbc':
$decryptedString = openssl_decrypt(
$encryptedData,
Expand All @@ -207,7 +217,7 @@ public function decrypt(string $string, string $secretKey = null)
throw new \Exception('Unsupported cipher method');
}
if ($decryptedString === false) {
throw new \Exception('Decryption failed');
throw new \Exception('Decryption failed: ' . openssl_error_string());
}

return $decryptedString;
Expand Down
6 changes: 4 additions & 2 deletions tests/DgcryptTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ public function testEncryptDecryptWithModifiedData()
$encrypted = $dgcrypt->encrypt($this->originalText);

// Modify encrypted data
$encrypted[10] = ($encrypted[10] === 'a') ? 'b' : 'a';
$decodedString = base64_decode($encrypted);
$decodedString[10] = ($decodedString[10] === 'a') ? 'b' : 'a';
$modifiedEncrypted = base64_encode($decodedString);

$this->expectException(\Exception::class);
$dgcrypt->decrypt($encrypted);
$dgcrypt->decrypt($modifiedEncrypted);
}
}

0 comments on commit c0acaef

Please sign in to comment.