diff --git a/src/Crypto.php b/src/Crypto.php index 53eb9c4..5605a11 100644 --- a/src/Crypto.php +++ b/src/Crypto.php @@ -73,7 +73,7 @@ public static function decrypt($ciphertext, Key $key, $raw_binary = false) * derivation function to make password cracking more expensive. * * @param string $ciphertext - * @param Key $key + * @param string $password * @param bool $raw_binary * * @throws Defuse\Crypto\Exception\EnvironmentIsBrokenException diff --git a/src/KeyOrPassword.php b/src/KeyOrPassword.php index 61ddb83..0426c23 100644 --- a/src/KeyOrPassword.php +++ b/src/KeyOrPassword.php @@ -70,9 +70,15 @@ public function deriveKeys($salt) ); return new DerivedKeys($akey, $ekey); } elseif ($this->secret_type === self::SECRET_TYPE_PASSWORD) { + /* Our PBKDF2 polyfill is vulnerable to a DoS attack documented in + * GitHub issue #230. The fix is to pre-hash the password to ensure + * it is short. We do the prehashing here instead of in pbkdf2() so + * that pbkdf2() still computes the function as defined by the + * standard. */ + $prehash = \hash(Core::HASH_FUNCTION_NAME, $this->secret, true); $prekey = Core::pbkdf2( - 'sha256', - $this->secret, + Core::HASH_FUNCTION_NAME, + $prehash, $salt, self::PBKDF2_ITERATIONS, Core::KEY_BYTE_SIZE, diff --git a/test/unit/CryptoTest.php b/test/unit/CryptoTest.php index 28d0e89..cb8742e 100644 --- a/test/unit/CryptoTest.php +++ b/test/unit/CryptoTest.php @@ -84,4 +84,22 @@ public function testEncryptDecryptWithPassword() } catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */ } } + + /** + * @expectedException \Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException + */ + public function testDecryptRawAsHex() + { + $ciphertext = Crypto::encryptWithPassword("testdata", "password", true); + Crypto::decryptWithPassword($ciphertext, "password", false); + } + + /** + * @expectedException \Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException + */ + public function testDecryptHexAsRaw() + { + $ciphertext = Crypto::encryptWithPassword("testdata", "password", false); + Crypto::decryptWithPassword($ciphertext, "password", true); + } } diff --git a/test/unit/PasswordTest.php b/test/unit/PasswordTest.php index 2a47fc5..93805fb 100644 --- a/test/unit/PasswordTest.php +++ b/test/unit/PasswordTest.php @@ -4,7 +4,7 @@ class PasswordTest extends PHPUnit_Framework_TestCase { - public function testKeyFromPasswordCorrect() + public function testKeyProtectedByPasswordCorrect() { $pkey1 = KeyProtectedByPassword::createRandomPasswordProtectedKey('password'); $pkey2 = KeyProtectedByPassword::loadFromAsciiSafeString($pkey1->saveToAsciiSafeString()); @@ -18,7 +18,7 @@ public function testKeyFromPasswordCorrect() /** * @expectedException \Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException */ - public function testKeyFromPasswordWrong() + public function testKeyProtectedByPasswordWrong() { $pkey = KeyProtectedByPassword::createRandomPasswordProtectedKey('rightpassword'); $key1 = $pkey->unlockKey('wrongpassword');