|
@@ -26,7 +26,7 @@ class Decryptor extends Cryptor {
|
|
|
}
|
|
|
|
|
|
$key = $this->_generateKey($components->headers->encSalt, $password);
|
|
|
-
|
|
|
+ $plaintext = null;
|
|
|
switch ($this->_settings->mode) {
|
|
|
case 'ctr':
|
|
|
$plaintext = $this->_aesCtrLittleEndianCrypt($components->ciphertext, $key, $components->headers->iv);
|
|
@@ -41,22 +41,41 @@ class Decryptor extends Cryptor {
|
|
|
return $plaintext;
|
|
|
}
|
|
|
|
|
|
- private function _unpackEncryptedBase64Data($encryptedBase64Data) {
|
|
|
+ public function decryptWithArbitraryKeys($encryptedBase64Data, $encKey, $hmacKey) {
|
|
|
+ $components = $this->_unpackEncryptedBase64Data($encryptedBase64Data, false);
|
|
|
+ if (!$this->_hmacIsValid($components, $hmacKey, false)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $plaintext = null;
|
|
|
+ switch ($this->_settings->mode) {
|
|
|
+ case 'ctr':
|
|
|
+ $plaintext = $this->_aesCtrLittleEndianCrypt($components->ciphertext, $encKey, $components->headers->iv);
|
|
|
+ break;
|
|
|
+ case 'cbc':
|
|
|
+ $paddedPlaintext = mcrypt_decrypt($this->_settings->algorithm, $encKey, $components->ciphertext, 'cbc', $components->headers->iv);
|
|
|
+ $plaintext = $this->_stripPKCS7Padding($paddedPlaintext);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return $plaintext;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function _unpackEncryptedBase64Data($encryptedBase64Data, $isPasswordBased = true) {
|
|
|
|
|
|
$binaryData = base64_decode($encryptedBase64Data);
|
|
|
|
|
|
$components = new \stdClass();
|
|
|
- $components->headers = $this->_parseHeaders($binaryData);
|
|
|
+ $components->headers = $this->_parseHeaders($binaryData, $isPasswordBased);
|
|
|
|
|
|
$components->hmac = substr($binaryData, - $this->_settings->hmac->length);
|
|
|
|
|
|
$headerLength = $components->headers->length;
|
|
|
+
|
|
|
$components->ciphertext = substr($binaryData, $headerLength, strlen($binaryData) - $headerLength - strlen($components->hmac));
|
|
|
|
|
|
return $components;
|
|
|
}
|
|
|
|
|
|
- private function _parseHeaders($binData) {
|
|
|
+ private function _parseHeaders($binData, $isPasswordBased = true) {
|
|
|
|
|
|
$offset = 0;
|
|
|
|
|
@@ -68,11 +87,15 @@ class Decryptor extends Cryptor {
|
|
|
$optionsChr = $binData[1];
|
|
|
$offset += strlen($optionsChr);
|
|
|
|
|
|
- $encSalt = substr($binData, $offset, $this->_settings->saltLength);
|
|
|
- $offset += strlen($encSalt);
|
|
|
+ $encSalt = null;
|
|
|
+ $hmacSalt = null;
|
|
|
+ if($isPasswordBased) {
|
|
|
+ $encSalt = substr($binData, $offset, $this->_settings->saltLength);
|
|
|
+ $offset += strlen($encSalt);
|
|
|
|
|
|
- $hmacSalt = substr($binData, $offset, $this->_settings->saltLength);
|
|
|
- $offset += strlen($hmacSalt);
|
|
|
+ $hmacSalt = substr($binData, $offset, $this->_settings->saltLength);
|
|
|
+ $offset += strlen($hmacSalt);
|
|
|
+ }
|
|
|
|
|
|
$iv = substr($binData, $offset, $this->_settings->ivLength);
|
|
|
$offset += strlen($iv);
|
|
@@ -94,8 +117,12 @@ class Decryptor extends Cryptor {
|
|
|
return substr($plaintext, 0, strlen($plaintext) - $padLength);
|
|
|
}
|
|
|
|
|
|
- private function _hmacIsValid($components, $password) {
|
|
|
- $hmacKey = $this->_generateKey($components->headers->hmacSalt, $password);
|
|
|
+ private function _hmacIsValid($components, $password, $isPasswordBased = true) {
|
|
|
+ $hmacKey = null;
|
|
|
+ if($isPasswordBased)
|
|
|
+ $hmacKey = $this->_generateKey($components->headers->hmacSalt, $password);
|
|
|
+ else
|
|
|
+ $hmacKey = $password;
|
|
|
return hash_equals($components->hmac, $this->_generateHmac($components, $hmacKey));
|
|
|
}
|
|
|
|