From 6f39fccd592fb205735a890c5bff7f6f47fa028f Mon Sep 17 00:00:00 2001 From: Taylor Hornby Date: Mon, 18 Apr 2016 18:10:23 -0600 Subject: [PATCH 1/4] Prehash the password before PBKDF2 --- src/KeyOrPassword.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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, From 5e419cb788eb9e624e164b7f15d6880573c3797e Mon Sep 17 00:00:00 2001 From: Taylor Hornby Date: Mon, 18 Apr 2016 18:13:51 -0600 Subject: [PATCH 2/4] Fix typo --- src/Crypto.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 1234a515118be658d52657263d9dbe28c13fa489 Mon Sep 17 00:00:00 2001 From: Taylor Hornby Date: Mon, 18 Apr 2016 18:19:47 -0600 Subject: [PATCH 3/4] Rename a test appropriately. --- test/unit/PasswordTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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'); From 090ad908e017be1662bffcd6e819ff64ad5f9cc3 Mon Sep 17 00:00:00 2001 From: Taylor Hornby Date: Mon, 18 Apr 2016 18:23:25 -0600 Subject: [PATCH 4/4] Test the case where wrong hex/raw parameter is given. --- test/unit/CryptoTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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); + } }