Completed
Push — master ( d1420e...cb0dbf )
by Morris
21:35
created
lib/public/Security/StringUtils.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
Please login to merge, or discard this patch.
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -32,18 +32,18 @@
 block discarded – undo
32 32
  * @since 8.0.0
33 33
  */
34 34
 class StringUtils {
35
-	/**
36
-	 * Compares whether two strings are equal. To prevent guessing of the string
37
-	 * length this is done by comparing two hashes against each other and afterwards
38
-	 * a comparison of the real string to prevent against the unlikely chance of
39
-	 * collisions.
40
-	 * @param string $expected The expected value
41
-	 * @param string $input The input to compare against
42
-	 * @return bool True if the two strings are equal, otherwise false.
43
-	 * @since 8.0.0
44
-	 * @deprecated 9.0.0 Use hash_equals
45
-	 */
46
-	public static function equals(string $expected, string $input): bool {
47
-		return hash_equals($expected, $input);
48
-	}
35
+    /**
36
+     * Compares whether two strings are equal. To prevent guessing of the string
37
+     * length this is done by comparing two hashes against each other and afterwards
38
+     * a comparison of the real string to prevent against the unlikely chance of
39
+     * collisions.
40
+     * @param string $expected The expected value
41
+     * @param string $input The input to compare against
42
+     * @return bool True if the two strings are equal, otherwise false.
43
+     * @since 8.0.0
44
+     * @deprecated 9.0.0 Use hash_equals
45
+     */
46
+    public static function equals(string $expected, string $input): bool {
47
+        return hash_equals($expected, $input);
48
+    }
49 49
 }
Please login to merge, or discard this patch.
lib/public/Security/ICrypto.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
Please login to merge, or discard this patch.
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -37,30 +37,30 @@
 block discarded – undo
37 37
  */
38 38
 interface ICrypto {
39 39
 
40
-	/**
41
-	 * @param string $message The message to authenticate
42
-	 * @param string $password Password to use (defaults to `secret` in config.php)
43
-	 * @return string Calculated HMAC
44
-	 * @since 8.0.0
45
-	 */
46
-	public function calculateHMAC(string $message, string $password = ''): string;
40
+    /**
41
+     * @param string $message The message to authenticate
42
+     * @param string $password Password to use (defaults to `secret` in config.php)
43
+     * @return string Calculated HMAC
44
+     * @since 8.0.0
45
+     */
46
+    public function calculateHMAC(string $message, string $password = ''): string;
47 47
 
48
-	/**
49
-	 * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
50
-	 * @param string $plaintext
51
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
52
-	 * @return string Authenticated ciphertext
53
-	 * @since 8.0.0
54
-	 */
55
-	public function encrypt(string $plaintext, string $password = ''): string;
48
+    /**
49
+     * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
50
+     * @param string $plaintext
51
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
52
+     * @return string Authenticated ciphertext
53
+     * @since 8.0.0
54
+     */
55
+    public function encrypt(string $plaintext, string $password = ''): string;
56 56
 
57
-	/**
58
-	 * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
59
-	 * @param string $authenticatedCiphertext
60
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
61
-	 * @return string plaintext
62
-	 * @throws \Exception If the HMAC does not match
63
-	 * @since 8.0.0
64
-	 */
65
-	public function decrypt(string $authenticatedCiphertext, string $password = ''): string;
57
+    /**
58
+     * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
59
+     * @param string $authenticatedCiphertext
60
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
61
+     * @return string plaintext
62
+     * @throws \Exception If the HMAC does not match
63
+     * @since 8.0.0
64
+     */
65
+    public function decrypt(string $authenticatedCiphertext, string $password = ''): string;
66 66
 }
Please login to merge, or discard this patch.
lib/public/Security/IHasher.php 2 patches
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -45,23 +45,23 @@
 block discarded – undo
45 45
  * @since 8.0.0
46 46
  */
47 47
 interface IHasher {
48
-	/**
49
-	 * Hashes a message using PHP's `password_hash` functionality.
50
-	 * Please note that the size of the returned string is not guaranteed
51
-	 * and can be up to 255 characters.
52
-	 *
53
-	 * @param string $message Message to generate hash from
54
-	 * @return string Hash of the message with appended version parameter
55
-	 * @since 8.0.0
56
-	 */
57
-	public function hash(string $message): string;
48
+    /**
49
+     * Hashes a message using PHP's `password_hash` functionality.
50
+     * Please note that the size of the returned string is not guaranteed
51
+     * and can be up to 255 characters.
52
+     *
53
+     * @param string $message Message to generate hash from
54
+     * @return string Hash of the message with appended version parameter
55
+     * @since 8.0.0
56
+     */
57
+    public function hash(string $message): string;
58 58
 
59
-	/**
60
-	 * @param string $message Message to verify
61
-	 * @param string $hash Assumed hash of the message
62
-	 * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
63
-	 * @return bool Whether $hash is a valid hash of $message
64
-	 * @since 8.0.0
65
-	 */
66
-	public function verify(string $message, string $hash, &$newHash = null): bool ;
59
+    /**
60
+     * @param string $message Message to verify
61
+     * @param string $hash Assumed hash of the message
62
+     * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
63
+     * @return bool Whether $hash is a valid hash of $message
64
+     * @since 8.0.0
65
+     */
66
+    public function verify(string $message, string $hash, &$newHash = null): bool ;
67 67
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
@@ -63,5 +63,5 @@  discard block
 block discarded – undo
63 63
 	 * @return bool Whether $hash is a valid hash of $message
64 64
 	 * @since 8.0.0
65 65
 	 */
66
-	public function verify(string $message, string $hash, &$newHash = null): bool ;
66
+	public function verify(string $message, string $hash, &$newHash = null): bool;
67 67
 }
Please login to merge, or discard this patch.
lib/private/Security/Hasher.php 2 patches
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -48,116 +48,116 @@
 block discarded – undo
48 48
  * @package OC\Security
49 49
  */
50 50
 class Hasher implements IHasher {
51
-	/** @var IConfig */
52
-	private $config;
53
-	/** @var array Options passed to password_hash and password_needs_rehash */
54
-	private $options = array();
55
-	/** @var string Salt used for legacy passwords */
56
-	private $legacySalt = null;
57
-	/** @var int Current version of the generated hash */
58
-	private $currentVersion = 1;
59
-
60
-	/**
61
-	 * @param IConfig $config
62
-	 */
63
-	public function __construct(IConfig $config) {
64
-		$this->config = $config;
65
-
66
-		$hashingCost = $this->config->getSystemValue('hashingCost', null);
67
-		if(!\is_null($hashingCost)) {
68
-			$this->options['cost'] = $hashingCost;
69
-		}
70
-	}
71
-
72
-	/**
73
-	 * Hashes a message using PHP's `password_hash` functionality.
74
-	 * Please note that the size of the returned string is not guaranteed
75
-	 * and can be up to 255 characters.
76
-	 *
77
-	 * @param string $message Message to generate hash from
78
-	 * @return string Hash of the message with appended version parameter
79
-	 */
80
-	public function hash(string $message): string {
81
-		return $this->currentVersion . '|' . password_hash($message, PASSWORD_DEFAULT, $this->options);
82
-	}
83
-
84
-	/**
85
-	 * Get the version and hash from a prefixedHash
86
-	 * @param string $prefixedHash
87
-	 * @return null|array Null if the hash is not prefixed, otherwise array('version' => 1, 'hash' => 'foo')
88
-	 */
89
-	protected function splitHash(string $prefixedHash) {
90
-		$explodedString = explode('|', $prefixedHash, 2);
91
-		if(\count($explodedString) === 2) {
92
-			if((int)$explodedString[0] > 0) {
93
-				return array('version' => (int)$explodedString[0], 'hash' => $explodedString[1]);
94
-			}
95
-		}
96
-
97
-		return null;
98
-	}
99
-
100
-	/**
101
-	 * Verify legacy hashes
102
-	 * @param string $message Message to verify
103
-	 * @param string $hash Assumed hash of the message
104
-	 * @param null|string &$newHash Reference will contain the updated hash
105
-	 * @return bool Whether $hash is a valid hash of $message
106
-	 */
107
-	protected function legacyHashVerify($message, $hash, &$newHash = null): bool {
108
-		if(empty($this->legacySalt)) {
109
-			$this->legacySalt = $this->config->getSystemValue('passwordsalt', '');
110
-		}
111
-
112
-		// Verify whether it matches a legacy PHPass or SHA1 string
113
-		$hashLength = \strlen($hash);
114
-		if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) ||
115
-			$hashLength === 40 && hash_equals($hash, sha1($message))) {
116
-			$newHash = $this->hash($message);
117
-			return true;
118
-		}
119
-
120
-		return false;
121
-	}
122
-
123
-	/**
124
-	 * Verify V1 hashes
125
-	 * @param string $message Message to verify
126
-	 * @param string $hash Assumed hash of the message
127
-	 * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
128
-	 * @return bool Whether $hash is a valid hash of $message
129
-	 */
130
-	protected function verifyHashV1(string $message, string $hash, &$newHash = null): bool {
131
-		if(password_verify($message, $hash)) {
132
-			if(password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) {
133
-				$newHash = $this->hash($message);
134
-			}
135
-			return true;
136
-		}
137
-
138
-		return false;
139
-	}
140
-
141
-	/**
142
-	 * @param string $message Message to verify
143
-	 * @param string $hash Assumed hash of the message
144
-	 * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
145
-	 * @return bool Whether $hash is a valid hash of $message
146
-	 */
147
-	public function verify(string $message, string $hash, &$newHash = null): bool {
148
-		$splittedHash = $this->splitHash($hash);
149
-
150
-		if(isset($splittedHash['version'])) {
151
-			switch ($splittedHash['version']) {
152
-				case 1:
153
-					return $this->verifyHashV1($message, $splittedHash['hash'], $newHash);
154
-			}
155
-		} else {
156
-			return $this->legacyHashVerify($message, $hash, $newHash);
157
-		}
158
-
159
-
160
-		return false;
161
-	}
51
+    /** @var IConfig */
52
+    private $config;
53
+    /** @var array Options passed to password_hash and password_needs_rehash */
54
+    private $options = array();
55
+    /** @var string Salt used for legacy passwords */
56
+    private $legacySalt = null;
57
+    /** @var int Current version of the generated hash */
58
+    private $currentVersion = 1;
59
+
60
+    /**
61
+     * @param IConfig $config
62
+     */
63
+    public function __construct(IConfig $config) {
64
+        $this->config = $config;
65
+
66
+        $hashingCost = $this->config->getSystemValue('hashingCost', null);
67
+        if(!\is_null($hashingCost)) {
68
+            $this->options['cost'] = $hashingCost;
69
+        }
70
+    }
71
+
72
+    /**
73
+     * Hashes a message using PHP's `password_hash` functionality.
74
+     * Please note that the size of the returned string is not guaranteed
75
+     * and can be up to 255 characters.
76
+     *
77
+     * @param string $message Message to generate hash from
78
+     * @return string Hash of the message with appended version parameter
79
+     */
80
+    public function hash(string $message): string {
81
+        return $this->currentVersion . '|' . password_hash($message, PASSWORD_DEFAULT, $this->options);
82
+    }
83
+
84
+    /**
85
+     * Get the version and hash from a prefixedHash
86
+     * @param string $prefixedHash
87
+     * @return null|array Null if the hash is not prefixed, otherwise array('version' => 1, 'hash' => 'foo')
88
+     */
89
+    protected function splitHash(string $prefixedHash) {
90
+        $explodedString = explode('|', $prefixedHash, 2);
91
+        if(\count($explodedString) === 2) {
92
+            if((int)$explodedString[0] > 0) {
93
+                return array('version' => (int)$explodedString[0], 'hash' => $explodedString[1]);
94
+            }
95
+        }
96
+
97
+        return null;
98
+    }
99
+
100
+    /**
101
+     * Verify legacy hashes
102
+     * @param string $message Message to verify
103
+     * @param string $hash Assumed hash of the message
104
+     * @param null|string &$newHash Reference will contain the updated hash
105
+     * @return bool Whether $hash is a valid hash of $message
106
+     */
107
+    protected function legacyHashVerify($message, $hash, &$newHash = null): bool {
108
+        if(empty($this->legacySalt)) {
109
+            $this->legacySalt = $this->config->getSystemValue('passwordsalt', '');
110
+        }
111
+
112
+        // Verify whether it matches a legacy PHPass or SHA1 string
113
+        $hashLength = \strlen($hash);
114
+        if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) ||
115
+            $hashLength === 40 && hash_equals($hash, sha1($message))) {
116
+            $newHash = $this->hash($message);
117
+            return true;
118
+        }
119
+
120
+        return false;
121
+    }
122
+
123
+    /**
124
+     * Verify V1 hashes
125
+     * @param string $message Message to verify
126
+     * @param string $hash Assumed hash of the message
127
+     * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
128
+     * @return bool Whether $hash is a valid hash of $message
129
+     */
130
+    protected function verifyHashV1(string $message, string $hash, &$newHash = null): bool {
131
+        if(password_verify($message, $hash)) {
132
+            if(password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) {
133
+                $newHash = $this->hash($message);
134
+            }
135
+            return true;
136
+        }
137
+
138
+        return false;
139
+    }
140
+
141
+    /**
142
+     * @param string $message Message to verify
143
+     * @param string $hash Assumed hash of the message
144
+     * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one.
145
+     * @return bool Whether $hash is a valid hash of $message
146
+     */
147
+    public function verify(string $message, string $hash, &$newHash = null): bool {
148
+        $splittedHash = $this->splitHash($hash);
149
+
150
+        if(isset($splittedHash['version'])) {
151
+            switch ($splittedHash['version']) {
152
+                case 1:
153
+                    return $this->verifyHashV1($message, $splittedHash['hash'], $newHash);
154
+            }
155
+        } else {
156
+            return $this->legacyHashVerify($message, $hash, $newHash);
157
+        }
158
+
159
+
160
+        return false;
161
+    }
162 162
 
163 163
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 		$this->config = $config;
65 65
 
66 66
 		$hashingCost = $this->config->getSystemValue('hashingCost', null);
67
-		if(!\is_null($hashingCost)) {
67
+		if (!\is_null($hashingCost)) {
68 68
 			$this->options['cost'] = $hashingCost;
69 69
 		}
70 70
 	}
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 	 * @return string Hash of the message with appended version parameter
79 79
 	 */
80 80
 	public function hash(string $message): string {
81
-		return $this->currentVersion . '|' . password_hash($message, PASSWORD_DEFAULT, $this->options);
81
+		return $this->currentVersion.'|'.password_hash($message, PASSWORD_DEFAULT, $this->options);
82 82
 	}
83 83
 
84 84
 	/**
@@ -88,9 +88,9 @@  discard block
 block discarded – undo
88 88
 	 */
89 89
 	protected function splitHash(string $prefixedHash) {
90 90
 		$explodedString = explode('|', $prefixedHash, 2);
91
-		if(\count($explodedString) === 2) {
92
-			if((int)$explodedString[0] > 0) {
93
-				return array('version' => (int)$explodedString[0], 'hash' => $explodedString[1]);
91
+		if (\count($explodedString) === 2) {
92
+			if ((int) $explodedString[0] > 0) {
93
+				return array('version' => (int) $explodedString[0], 'hash' => $explodedString[1]);
94 94
 			}
95 95
 		}
96 96
 
@@ -105,13 +105,13 @@  discard block
 block discarded – undo
105 105
 	 * @return bool Whether $hash is a valid hash of $message
106 106
 	 */
107 107
 	protected function legacyHashVerify($message, $hash, &$newHash = null): bool {
108
-		if(empty($this->legacySalt)) {
108
+		if (empty($this->legacySalt)) {
109 109
 			$this->legacySalt = $this->config->getSystemValue('passwordsalt', '');
110 110
 		}
111 111
 
112 112
 		// Verify whether it matches a legacy PHPass or SHA1 string
113 113
 		$hashLength = \strlen($hash);
114
-		if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) ||
114
+		if ($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) ||
115 115
 			$hashLength === 40 && hash_equals($hash, sha1($message))) {
116 116
 			$newHash = $this->hash($message);
117 117
 			return true;
@@ -128,8 +128,8 @@  discard block
 block discarded – undo
128 128
 	 * @return bool Whether $hash is a valid hash of $message
129 129
 	 */
130 130
 	protected function verifyHashV1(string $message, string $hash, &$newHash = null): bool {
131
-		if(password_verify($message, $hash)) {
132
-			if(password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) {
131
+		if (password_verify($message, $hash)) {
132
+			if (password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) {
133 133
 				$newHash = $this->hash($message);
134 134
 			}
135 135
 			return true;
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
 	public function verify(string $message, string $hash, &$newHash = null): bool {
148 148
 		$splittedHash = $this->splitHash($hash);
149 149
 
150
-		if(isset($splittedHash['version'])) {
150
+		if (isset($splittedHash['version'])) {
151 151
 			switch ($splittedHash['version']) {
152 152
 				case 1:
153 153
 					return $this->verifyHashV1($message, $splittedHash['hash'], $newHash);
Please login to merge, or discard this patch.
lib/private/Security/Crypto.php 2 patches
Indentation   +88 added lines, -88 removed lines patch added patch discarded remove patch
@@ -44,93 +44,93 @@
 block discarded – undo
44 44
  * @package OC\Security
45 45
  */
46 46
 class Crypto implements ICrypto {
47
-	/** @var AES $cipher */
48
-	private $cipher;
49
-	/** @var int */
50
-	private $ivLength = 16;
51
-	/** @var IConfig */
52
-	private $config;
53
-	/** @var ISecureRandom */
54
-	private $random;
55
-
56
-	/**
57
-	 * @param IConfig $config
58
-	 * @param ISecureRandom $random
59
-	 */
60
-	public function __construct(IConfig $config, ISecureRandom $random) {
61
-		$this->cipher = new AES();
62
-		$this->config = $config;
63
-		$this->random = $random;
64
-	}
65
-
66
-	/**
67
-	 * @param string $message The message to authenticate
68
-	 * @param string $password Password to use (defaults to `secret` in config.php)
69
-	 * @return string Calculated HMAC
70
-	 */
71
-	public function calculateHMAC(string $message, string $password = ''): string {
72
-		if($password === '') {
73
-			$password = $this->config->getSystemValue('secret');
74
-		}
75
-
76
-		// Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
-		$password = hash('sha512', $password . 'a');
78
-
79
-		$hash = new Hash('sha512');
80
-		$hash->setKey($password);
81
-		return $hash->hash($message);
82
-	}
83
-
84
-	/**
85
-	 * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
86
-	 * @param string $plaintext
87
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
88
-	 * @return string Authenticated ciphertext
89
-	 */
90
-	public function encrypt(string $plaintext, string $password = ''): string {
91
-		if($password === '') {
92
-			$password = $this->config->getSystemValue('secret');
93
-		}
94
-		$this->cipher->setPassword($password);
95
-
96
-		$iv = $this->random->generate($this->ivLength);
97
-		$this->cipher->setIV($iv);
98
-
99
-		$ciphertext = bin2hex($this->cipher->encrypt($plaintext));
100
-		$hmac = bin2hex($this->calculateHMAC($ciphertext.$iv, $password));
101
-
102
-		return $ciphertext.'|'.$iv.'|'.$hmac;
103
-	}
104
-
105
-	/**
106
-	 * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
107
-	 * @param string $authenticatedCiphertext
108
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
109
-	 * @return string plaintext
110
-	 * @throws \Exception If the HMAC does not match
111
-	 */
112
-	public function decrypt(string $authenticatedCiphertext, string $password = ''): string {
113
-		if($password === '') {
114
-			$password = $this->config->getSystemValue('secret');
115
-		}
116
-		$this->cipher->setPassword($password);
117
-
118
-		$parts = explode('|', $authenticatedCiphertext);
119
-		if(\count($parts) !== 3) {
120
-			throw new \Exception('Authenticated ciphertext could not be decoded.');
121
-		}
122
-
123
-		$ciphertext = hex2bin($parts[0]);
124
-		$iv = $parts[1];
125
-		$hmac = hex2bin($parts[2]);
126
-
127
-		$this->cipher->setIV($iv);
128
-
129
-		if(!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
130
-			throw new \Exception('HMAC does not match.');
131
-		}
132
-
133
-		return $this->cipher->decrypt($ciphertext);
134
-	}
47
+    /** @var AES $cipher */
48
+    private $cipher;
49
+    /** @var int */
50
+    private $ivLength = 16;
51
+    /** @var IConfig */
52
+    private $config;
53
+    /** @var ISecureRandom */
54
+    private $random;
55
+
56
+    /**
57
+     * @param IConfig $config
58
+     * @param ISecureRandom $random
59
+     */
60
+    public function __construct(IConfig $config, ISecureRandom $random) {
61
+        $this->cipher = new AES();
62
+        $this->config = $config;
63
+        $this->random = $random;
64
+    }
65
+
66
+    /**
67
+     * @param string $message The message to authenticate
68
+     * @param string $password Password to use (defaults to `secret` in config.php)
69
+     * @return string Calculated HMAC
70
+     */
71
+    public function calculateHMAC(string $message, string $password = ''): string {
72
+        if($password === '') {
73
+            $password = $this->config->getSystemValue('secret');
74
+        }
75
+
76
+        // Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
+        $password = hash('sha512', $password . 'a');
78
+
79
+        $hash = new Hash('sha512');
80
+        $hash->setKey($password);
81
+        return $hash->hash($message);
82
+    }
83
+
84
+    /**
85
+     * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
86
+     * @param string $plaintext
87
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
88
+     * @return string Authenticated ciphertext
89
+     */
90
+    public function encrypt(string $plaintext, string $password = ''): string {
91
+        if($password === '') {
92
+            $password = $this->config->getSystemValue('secret');
93
+        }
94
+        $this->cipher->setPassword($password);
95
+
96
+        $iv = $this->random->generate($this->ivLength);
97
+        $this->cipher->setIV($iv);
98
+
99
+        $ciphertext = bin2hex($this->cipher->encrypt($plaintext));
100
+        $hmac = bin2hex($this->calculateHMAC($ciphertext.$iv, $password));
101
+
102
+        return $ciphertext.'|'.$iv.'|'.$hmac;
103
+    }
104
+
105
+    /**
106
+     * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
107
+     * @param string $authenticatedCiphertext
108
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
109
+     * @return string plaintext
110
+     * @throws \Exception If the HMAC does not match
111
+     */
112
+    public function decrypt(string $authenticatedCiphertext, string $password = ''): string {
113
+        if($password === '') {
114
+            $password = $this->config->getSystemValue('secret');
115
+        }
116
+        $this->cipher->setPassword($password);
117
+
118
+        $parts = explode('|', $authenticatedCiphertext);
119
+        if(\count($parts) !== 3) {
120
+            throw new \Exception('Authenticated ciphertext could not be decoded.');
121
+        }
122
+
123
+        $ciphertext = hex2bin($parts[0]);
124
+        $iv = $parts[1];
125
+        $hmac = hex2bin($parts[2]);
126
+
127
+        $this->cipher->setIV($iv);
128
+
129
+        if(!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
130
+            throw new \Exception('HMAC does not match.');
131
+        }
132
+
133
+        return $this->cipher->decrypt($ciphertext);
134
+    }
135 135
 
136 136
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
@@ -69,12 +69,12 @@  discard block
 block discarded – undo
69 69
 	 * @return string Calculated HMAC
70 70
 	 */
71 71
 	public function calculateHMAC(string $message, string $password = ''): string {
72
-		if($password === '') {
72
+		if ($password === '') {
73 73
 			$password = $this->config->getSystemValue('secret');
74 74
 		}
75 75
 
76 76
 		// Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
-		$password = hash('sha512', $password . 'a');
77
+		$password = hash('sha512', $password.'a');
78 78
 
79 79
 		$hash = new Hash('sha512');
80 80
 		$hash->setKey($password);
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
 	 * @return string Authenticated ciphertext
89 89
 	 */
90 90
 	public function encrypt(string $plaintext, string $password = ''): string {
91
-		if($password === '') {
91
+		if ($password === '') {
92 92
 			$password = $this->config->getSystemValue('secret');
93 93
 		}
94 94
 		$this->cipher->setPassword($password);
@@ -110,13 +110,13 @@  discard block
 block discarded – undo
110 110
 	 * @throws \Exception If the HMAC does not match
111 111
 	 */
112 112
 	public function decrypt(string $authenticatedCiphertext, string $password = ''): string {
113
-		if($password === '') {
113
+		if ($password === '') {
114 114
 			$password = $this->config->getSystemValue('secret');
115 115
 		}
116 116
 		$this->cipher->setPassword($password);
117 117
 
118 118
 		$parts = explode('|', $authenticatedCiphertext);
119
-		if(\count($parts) !== 3) {
119
+		if (\count($parts) !== 3) {
120 120
 			throw new \Exception('Authenticated ciphertext could not be decoded.');
121 121
 		}
122 122
 
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
 
127 127
 		$this->cipher->setIV($iv);
128 128
 
129
-		if(!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
129
+		if (!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
130 130
 			throw new \Exception('HMAC does not match.');
131 131
 		}
132 132
 
Please login to merge, or discard this patch.