1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* OpensslWrapper.php |
5
|
|
|
* |
6
|
|
|
* PHP version 7 |
7
|
|
|
* |
8
|
|
|
* @category Dcrypt |
9
|
|
|
* @package Dcrypt |
10
|
|
|
* @author Michael Meyer (mmeyer2k) <[email protected]> |
11
|
|
|
* @license http://opensource.org/licenses/MIT The MIT License (MIT) |
12
|
|
|
* @link https://github.com/mmeyer2k/dcrypt |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace Dcrypt; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* A wrapper around any openssl_* functions. |
19
|
|
|
* |
20
|
|
|
* @category Dcrypt |
21
|
|
|
* @package Dcrypt |
22
|
|
|
* @author Michael Meyer (mmeyer2k) <[email protected]> |
23
|
|
|
* @license http://opensource.org/licenses/MIT The MIT License (MIT) |
24
|
|
|
* @link https://github.com/mmeyer2k/dcrypt |
25
|
|
|
*/ |
26
|
|
|
class OpensslWrapper |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* OpenSSL encrypt wrapper function |
30
|
|
|
* |
31
|
|
|
* @param string $input Data to decrypt |
32
|
|
|
* @param string $method Cipher method to use |
33
|
|
|
* @param string $key Key string |
34
|
|
|
* @param string $iv Initialization vector |
35
|
|
|
* @return string |
36
|
|
|
*/ |
37
|
|
View Code Duplication |
protected static function openssl_encrypt(string $input, string $method, string $key, string $iv, string &$tag): string |
|
|
|
|
38
|
|
|
{ |
39
|
|
|
if (OpensslStatic::tagRequired($method)) { |
|
|
|
|
40
|
|
|
$ret = \openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv, $tag, '', 4); |
41
|
|
|
} else { |
42
|
|
|
$ret = \openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
return self::returnOrException($ret); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* OpenSSL decrypt wrapper function |
50
|
|
|
* |
51
|
|
|
* @param string $input Data to decrypt |
52
|
|
|
* @param string $method Cipher method to use |
53
|
|
|
* @param string $key Key string |
54
|
|
|
* @param string $iv Initialization vector |
55
|
|
|
* @return string |
56
|
|
|
*/ |
57
|
|
View Code Duplication |
protected static function openssl_decrypt(string $input, string $method, string $key, string $iv, string $tag): string |
|
|
|
|
58
|
|
|
{ |
59
|
|
|
if (OpensslStatic::tagRequired($method)) { |
|
|
|
|
60
|
|
|
$ret = \openssl_decrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv, $tag, ''); |
61
|
|
|
} else { |
62
|
|
|
$ret = \openssl_decrypt($input, $method, $key, OPENSSL_RAW_DATA, $iv); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return self::returnOrException($ret); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Throw an exception if openssl function returns false |
70
|
|
|
* |
71
|
|
|
* @param string|bool $data |
72
|
|
|
* @return string |
73
|
|
|
* @throws \Exception |
74
|
|
|
*/ |
75
|
|
|
private static function returnOrException($data): string |
76
|
|
|
{ |
77
|
|
|
if ($data === false) { |
78
|
|
|
throw new \Exception('OpenSSL failed to encrypt/decrypt message.'); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
return $data; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Get IV size for specified CIPHER. |
86
|
|
|
* |
87
|
|
|
* @param string $cipher |
88
|
|
|
* @return int |
89
|
|
|
* @throws \Exception |
90
|
|
|
*/ |
91
|
|
|
protected static function ivSize(string $cipher): int |
92
|
|
|
{ |
93
|
|
|
$ret = \openssl_cipher_iv_length($cipher); |
94
|
|
|
|
95
|
|
|
if ($ret === false) { |
96
|
|
|
throw new \Exception("Failed to determine correct IV size."); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $ret; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Get a correctly sized IV for the specified cipher |
104
|
|
|
* |
105
|
|
|
* @param string $cipher |
106
|
|
|
* @return string |
107
|
|
|
* @throws \Exception |
108
|
|
|
*/ |
109
|
|
|
protected static function ivGenerate(string $cipher): string |
110
|
|
|
{ |
111
|
|
|
$size = self::ivSize($cipher); |
112
|
|
|
|
113
|
|
|
if ($size === 0) { |
114
|
|
|
return ''; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return \random_bytes($size); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Determines if the provided cipher requires a tag |
122
|
|
|
* |
123
|
|
|
* @param string $cipher |
124
|
|
|
* @return bool |
125
|
|
|
*/ |
126
|
|
|
protected static function tagRequired(string $cipher): bool |
127
|
|
|
{ |
128
|
|
|
$cipher = strtolower($cipher); |
129
|
|
|
|
130
|
|
|
$needle_tips = [ |
131
|
|
|
'-gcm', |
132
|
|
|
'-ccm', |
133
|
|
|
]; |
134
|
|
|
|
135
|
|
|
foreach ($needle_tips as $needle) { |
136
|
|
|
if (strpos($cipher, $needle)) { |
137
|
|
|
return true; |
138
|
|
|
} |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
return false; |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.