Skip to content
This repository was archived by the owner on Oct 5, 2022. It is now read-only.
Merged
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
21 changes: 16 additions & 5 deletions lib/phpSec/Crypt/Crypto.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,24 @@ public function encrypt($data, $key) {
return false;
}
} else {
/* No spsecific size is needed. */
/* No specific size is needed. */
if($keySize == 0 || $keySize > mcrypt_enc_get_key_size($td)) {
throw new \phpSec\Exception\InvalidKeySpecException('Key is out of range. Should be between 1 and ' . mcrypt_enc_get_key_size($td).' bytes.');
return false;
}
}

/* Using PBKDF with constant salts dedicated to each purpose
* can securely derivce two keys from one */
$key1 = $this->pbkdf2($key, "encrypt", 1, $keySize);
$key2 = $this->pbkdf2($key, "HMAC", 1, $keySize);

/* Create IV. */
$rnd = $this->psl['crypt/rand'];
$iv = $rnd->bytes(mcrypt_enc_get_iv_size($td));

/* Init mcrypt. */
mcrypt_generic_init($td, $key, $iv);
mcrypt_generic_init($td, $key1, $iv);

/* Prepeare the array with data. */
$serializedData = serialize($data);
Expand All @@ -111,7 +116,7 @@ public function encrypt($data, $key) {
$encrypted['iv'] = base64_encode($iv); /* Initialization vector, just a bunch of randomness. */
$encrypted['cdata'] = base64_encode(mcrypt_generic($td, $serializedData)); /* The encrypted data. */
$encrypted['mac'] = base64_encode( /* The message authentication code. Used to make sure the */
$this->pbkdf2($encrypted['cdata'], $key, 1000, 32) /* message is valid when decrypted. */
$this->pbkdf2($encrypted['cdata'], $key2, 1, 32) /* message is valid when decrypted. */
);
return json_encode($encrypted);
}
Expand Down Expand Up @@ -148,14 +153,20 @@ public function decrypt($data, $key) {
$td = mcrypt_module_open($data['algo'], '', $data['mode'], '');
$block = mcrypt_enc_get_block_size($td);

/* Using PBKDF with constant salts dedicated to each purpose
* can securely derivce two keys from one */
$keySize = strlen($key);
$key1 = $this->pbkdf2($key, "encrypt", 1, $keySize);
$key2 = $this->pbkdf2($key, "HMAC", 1, $keySize);

/* Check MAC. */
if(base64_decode($data['mac']) != $this->pbkdf2($data['cdata'], $key, 1000, 32)) {
if(base64_decode($data['mac']) != $this->pbkdf2($data['cdata'], $key2, 1, 32)) {
throw new \phpSec\Exception\GeneralSecurityException('Message authentication code invalid');
return false;
}

/* Init mcrypt. */
mcrypt_generic_init($td, $key, base64_decode($data['iv']));
mcrypt_generic_init($td, $key1, base64_decode($data['iv']));

$decrypted = rtrim(mdecrypt_generic($td, base64_decode($this->stripPadding($block, $data['cdata']))));

Expand Down
9 changes: 8 additions & 1 deletion tests/phpSec/Crypt/CryptoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ public function testCrypto() {

$str = 'foobaz';
$key = '123abc12123abc12';
$badkey = '123abcR77123abc12';


$encrypted = $crypto->encrypt($str, $key);

$decrypted = $crypto->decrypt($encrypted, $key);

$this->assertEquals($decrypted, $str);
try {
$ret = $crypto->decrypt($encrypted, $badkey);
}catch(Exception $e){
$this->assertEquals("Message authentication code invalid",$e->getMessage());
}

}
}
}