PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 3.8.1
WooCommerce Square v3.8.1
5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Utilities / Encryption_Utility.php
woocommerce-square / includes / Utilities Last commit date
Array_Utility.php 3 years ago Encryption_Utility.php 3 years ago Helper.php 3 years ago Money_Utility.php 3 years ago String_Utility.php 3 years ago
Encryption_Utility.php
264 lines
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
22 */
23
24 namespace WooCommerce\Square\Utilities;
25 use WooCommerce_Square_Loader;
26
27 defined( 'ABSPATH' ) || exit;
28
29 /**
30 * The encryption utility class.
31 *
32 * Requires OpenSSL by default.
33 *
34 * @since 2.0.0
35 */
36 class Encryption_Utility {
37
38
39 /** @var string default cipher method */
40 protected $default_cipher_method = 'AES-128-CBC';
41
42 /** @var string cipher method */
43 protected $cipher_method;
44
45
46 /**
47 * Constructs the class.
48 *
49 * @param string $preferred_cipher_method cipher method
50 */
51 public function __construct( $preferred_cipher_method = '' ) {
52
53 // bail entirely if openssl isn't available
54 if ( ! self::is_encryption_supported() ) {
55 wc_doing_it_wrong( __CLASS__, __( 'Encryption is not supported on this site.', 'woocommerce-square' ), WooCommerce_Square_Loader::FRAMEWORK_VERSION );
56 return;
57 }
58
59 $this->cipher_method = $this->get_default_cipher_method();
60
61 // if a preferred cipher method is set, check and set it
62 if ( is_string( $preferred_cipher_method ) && ! empty( $preferred_cipher_method ) ) {
63
64 // only use what's preferred if it's supported
65 if ( $this->is_cipher_method_supported( $preferred_cipher_method ) ) {
66
67 $this->cipher_method = $preferred_cipher_method;
68
69 } else { // otherwise, throw a notice and continue with the default
70
71 $message = sprintf(
72 __( '%1$s encryption is not available on this site. %2$s will be used instead.', 'woocommerce-square' ),
73 $preferred_cipher_method,
74 $this->cipher_method
75 );
76
77 wc_doing_it_wrong( __CLASS__, $message, WooCommerce_Square_Loader::FRAMEWORK_VERSION );
78 }
79 }
80 }
81
82
83 /**
84 * Encrypts data.
85 *
86 * @since 2.0.0
87 *
88 * @param string|array $data data to encrypt
89 * @param string $key encryption key
90 * @return string
91 * @throws \Exception
92 */
93 public function encrypt_data( $data, $key = '' ) {
94
95 // sanity check to ensure encryption can happen
96 if ( ! $this->get_cipher_method() ) {
97 throw new \Exception( __( 'No encryption method available', 'woocommerce-square' ) );
98 }
99
100 if ( empty( $data ) || ( ! is_string( $data ) && ! is_array( $data ) ) ) {
101 throw new \Exception( __( 'Data must be a non-empty string or array', 'woocommerce-square' ) );
102 }
103
104 if ( ! is_string( $key ) ) {
105 throw new \Exception( __( 'Encryption key must be a string', 'woocommerce-square' ) );
106 }
107
108 // default to the WP salt
109 if ( empty( $key ) ) {
110 $key = $this->get_default_key();
111 }
112
113 $vector = openssl_random_pseudo_bytes( $this->get_vector_length(), $crypto_strong );
114
115 // bail if a strong vector wasn't generated
116 if ( false === $vector || false === $crypto_strong ) {
117 throw new \Exception( __( 'Could not generate encryption vector.', 'woocommerce-square' ) );
118 }
119
120 $encrypted_data = openssl_encrypt( json_encode( $data ), $this->get_cipher_method(), $key, 0, $vector );
121
122 return base64_encode( $vector . $encrypted_data );
123 }
124
125
126 /**
127 * Decrypts data.
128 *
129 * @since 2.0.0
130 *
131 * @param string $data data to decrypt
132 * @param string $key decryption key
133 * @return string|array
134 * @throws \Exception
135 */
136 public function decrypt_data( $data, $key = '' ) {
137
138 // sanity check to ensure decryption can happen
139 if ( ! $this->get_cipher_method() ) {
140 throw new \Exception( __( 'No decryption method available', 'woocommerce-square' ) );
141 }
142
143 if ( empty( $data ) || ! is_string( $data ) ) {
144 throw new \Exception( __( 'Data must be a non-empty string', 'woocommerce-square' ) );
145 }
146
147 if ( ! is_string( $key ) ) {
148 throw new \Exception( __( 'Encryption key must be a string', 'woocommerce-square' ) );
149 }
150
151 // default to the WP salt
152 if ( empty( $key ) ) {
153 $key = $this->get_default_key();
154 }
155
156 $data = base64_decode( $data );
157
158 $vector_length = $this->get_vector_length();
159 $vector = substr( $data, 0, $vector_length );
160 $data = substr( $data, $vector_length );
161 $data = openssl_decrypt( $data, $this->get_cipher_method(), $key, 0, $vector );
162
163 return json_decode( $data, true );
164 }
165
166
167 /**
168 * Gets the vector length.
169 *
170 * @since 2.0.0
171 *
172 * @return int
173 */
174 protected function get_vector_length() {
175
176 return openssl_cipher_iv_length( $this->get_cipher_method() );
177 }
178
179
180 /**
181 * Determines if a cipher method is supported by the server.
182 *
183 * @since 2.0.0
184 *
185 * @param string $method cipher method to check
186 * @return bool
187 */
188 protected function is_cipher_method_supported( $method ) {
189
190 return in_array( $method, $this->get_supported_cipher_methods(), true );
191 }
192
193
194 /**
195 * Determines if encryption is supported at all.
196 *
197 * @since 2.0.0
198 *
199 * @return bool
200 */
201 public static function is_encryption_supported() {
202
203 return extension_loaded( 'openssl' );
204 }
205
206
207 /**
208 * Gets the cipher method.
209 *
210 * @since 2.0.0
211 *
212 * @return string
213 */
214 protected function get_cipher_method() {
215
216 return $this->cipher_method;
217 }
218
219
220 /**
221 * Gets the default cipher method.
222 *
223 * Checks the list of supported methods first, and if the default isn't supported, uses the first available.
224 *
225 * @since 2.0.0
226 *
227 * @return string
228 */
229 protected function get_default_cipher_method() {
230
231 $available_methods = $this->get_supported_cipher_methods();
232
233 return in_array( $this->default_cipher_method, $available_methods, true ) ? $this->default_cipher_method : $available_methods[0];
234 }
235
236
237 /**
238 * Gets the supported cipher methods.
239 *
240 * @since 2.0.0
241 *
242 * @return array
243 */
244 protected function get_supported_cipher_methods() {
245
246 return openssl_get_cipher_methods();
247 }
248
249
250 /**
251 * Gets the default encryption key.
252 *
253 * @since 2.0.0
254 *
255 * @return string
256 */
257 protected function get_default_key() {
258
259 return md5( wp_salt(), true );
260 }
261
262
263 }
264