7 |
- |
1 |
<?php
|
|
|
2 |
/**
|
|
|
3 |
* Openssl encrypt/decrypt functions
|
|
|
4 |
*
|
|
|
5 |
* Available under the MIT License
|
|
|
6 |
*
|
|
|
7 |
* The MIT License (MIT)
|
|
|
8 |
* Copyright (c) 2016 ionCube Ltd.
|
|
|
9 |
*
|
|
|
10 |
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
|
11 |
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
|
12 |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
13 |
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
14 |
*
|
|
|
15 |
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
|
|
16 |
* the Software.
|
|
|
17 |
*
|
|
|
18 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
|
19 |
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
|
|
20 |
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
|
|
21 |
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
22 |
*/
|
65 |
- |
23 |
class Cryptor {
|
7 |
- |
24 |
private static $instance = null;
|
|
|
25 |
private static $cipher_algo;
|
|
|
26 |
private static $hash_algo;
|
|
|
27 |
private static $keystring;
|
|
|
28 |
private static $iv_num_bytes;
|
|
|
29 |
private static $format;
|
9 |
- |
30 |
private static $hasOpenSSL = true;
|
7 |
- |
31 |
const FORMAT_RAW = 0;
|
|
|
32 |
const FORMAT_B64 = 1;
|
|
|
33 |
const FORMAT_HEX = 2;
|
|
|
34 |
|
|
|
35 |
/**
|
|
|
36 |
* Create a Cryptor singleton instance
|
|
|
37 |
* @param array $cryptConfig The cipher algorithm, the hash algorithm and the key.
|
|
|
38 |
* @param [type] $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX. Default: FORMAT_B64.
|
|
|
39 |
*/
|
65 |
- |
40 |
public static function getInstance($cryptorConfig = null, $fmt = Cryptor::FORMAT_B64) {
|
|
|
41 |
if (is_null(self::$instance)) {
|
7 |
- |
42 |
self::$instance = new self();
|
9 |
- |
43 |
if (!extension_loaded("openssl")) {
|
65 |
- |
44 |
self::$hasOpenSSL = false;
|
9 |
- |
45 |
return self::$instance;
|
|
|
46 |
}
|
65 |
- |
47 |
}
|
|
|
48 |
else {
|
7 |
- |
49 |
return self::$instance;
|
|
|
50 |
}
|
|
|
51 |
// store cryptor configuration
|
|
|
52 |
if (!is_null($cryptorConfig)) {
|
|
|
53 |
if (isset($cryptorConfig['cipherAlgorithm']) && !empty($cryptorConfig['cipherAlgorithm'])) {
|
|
|
54 |
self::$cipher_algo = $cryptorConfig['cipherAlgorithm'];
|
65 |
- |
55 |
}
|
|
|
56 |
else {
|
7 |
- |
57 |
self::$cipher_algo = 'aes-256-cbc';
|
|
|
58 |
}
|
|
|
59 |
if (isset($cryptorConfig['hashAlgorithm']) && !empty($cryptorConfig['hashAlgorithm'])) {
|
|
|
60 |
self::$hash_algo = $cryptorConfig['hashAlgorithm'];
|
65 |
- |
61 |
}
|
|
|
62 |
else {
|
7 |
- |
63 |
self::$hash_algo = 'sha256';
|
|
|
64 |
}
|
|
|
65 |
if (isset($cryptorConfig['key']) && !empty($cryptorConfig['key'])) {
|
|
|
66 |
self::$keystring = $cryptorConfig['key'];
|
65 |
- |
67 |
}
|
|
|
68 |
else {
|
7 |
- |
69 |
throw new \Exception("Cryptor:: - key not set in configuration");
|
|
|
70 |
}
|
|
|
71 |
if ($fmt === Cryptor::FORMAT_RAW || $fmt === Cryptor::FORMAT_B64 || $fmt == Cryptor::FORMAT_HEX) {
|
|
|
72 |
self::$format = $fmt;
|
65 |
- |
73 |
}
|
|
|
74 |
else {
|
7 |
- |
75 |
self::$format = Cryptor::FORMAT_B64;
|
|
|
76 |
}
|
|
|
77 |
}
|
|
|
78 |
|
65 |
- |
79 |
if (!in_array(self::$cipher_algo, openssl_get_cipher_methods(true))) {
|
7 |
- |
80 |
throw new \Exception("Cryptor:: - unknown cipher algo {" . self::$cipher_algo . "}");
|
|
|
81 |
}
|
|
|
82 |
|
65 |
- |
83 |
if (!in_array(self::$hash_algo, openssl_get_md_methods(true))) {
|
7 |
- |
84 |
throw new \Exception("Cryptor:: - unknown hash algo {" . self::$hash_algo . "}");
|
|
|
85 |
}
|
|
|
86 |
|
|
|
87 |
self::$iv_num_bytes = openssl_cipher_iv_length(self::$cipher_algo);
|
|
|
88 |
|
|
|
89 |
return self::$instance;
|
|
|
90 |
}
|
|
|
91 |
/**
|
|
|
92 |
* Encrypt a string.
|
|
|
93 |
* @param string $in String to encrypt.
|
|
|
94 |
* @param string $key Optional encryption key.
|
|
|
95 |
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
|
|
|
96 |
* @return string The encrypted string.
|
|
|
97 |
*/
|
65 |
- |
98 |
public static function encryptString($in, $key = null, $fmt = null) {
|
9 |
- |
99 |
if (!self::$hasOpenSSL) {
|
|
|
100 |
return base64_encode($in);
|
|
|
101 |
}
|
65 |
- |
102 |
if ($fmt === null) {
|
7 |
- |
103 |
$fmt = self::$format;
|
|
|
104 |
}
|
65 |
- |
105 |
if ($key === null) {
|
7 |
- |
106 |
$key = self::$keystring;
|
|
|
107 |
}
|
|
|
108 |
// Build an initialization vector
|
|
|
109 |
$iv = openssl_random_pseudo_bytes(self::$iv_num_bytes, $isStrongCrypto);
|
|
|
110 |
if (!$isStrongCrypto) {
|
|
|
111 |
throw new \Exception("Cryptor::encryptString() - Not a strong key");
|
|
|
112 |
}
|
|
|
113 |
// Hash the key
|
|
|
114 |
$keyhash = openssl_digest($key, self::$hash_algo, true);
|
|
|
115 |
// and encrypt
|
65 |
- |
116 |
$opts = OPENSSL_RAW_DATA;
|
7 |
- |
117 |
$encrypted = openssl_encrypt($in, self::$cipher_algo, $keyhash, $opts, $iv);
|
65 |
- |
118 |
if ($encrypted === false) {
|
7 |
- |
119 |
throw new \Exception('Cryptor::encryptString() - Encryption failed: ' . openssl_error_string());
|
|
|
120 |
}
|
|
|
121 |
// The result comprises the IV and encrypted data
|
|
|
122 |
$res = $iv . $encrypted;
|
|
|
123 |
// and format the result if required.
|
65 |
- |
124 |
if ($fmt == Cryptor::FORMAT_B64) {
|
7 |
- |
125 |
$res = base64_encode($res);
|
|
|
126 |
}
|
65 |
- |
127 |
else if ($fmt == Cryptor::FORMAT_HEX) {
|
|
|
128 |
$res = unpack('H*', $res) [1];
|
7 |
- |
129 |
}
|
|
|
130 |
return $res;
|
|
|
131 |
}
|
|
|
132 |
/**
|
|
|
133 |
* Decrypt a string.
|
|
|
134 |
* @param string $in String to decrypt.
|
|
|
135 |
* @param string $key Optional decryption key.
|
|
|
136 |
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
|
|
|
137 |
* @return string The decrypted string.
|
|
|
138 |
*/
|
65 |
- |
139 |
public static function decryptString($in, $key = null, $fmt = null) {
|
9 |
- |
140 |
if (!self::$hasOpenSSL) {
|
|
|
141 |
return base64_decode($in);
|
|
|
142 |
}
|
65 |
- |
143 |
if ($fmt === null) {
|
7 |
- |
144 |
$fmt = self::$format;
|
|
|
145 |
}
|
65 |
- |
146 |
if ($key === null) {
|
7 |
- |
147 |
$key = self::$keystring;
|
|
|
148 |
}
|
|
|
149 |
$raw = $in;
|
|
|
150 |
// Restore the encrypted data if encoded
|
65 |
- |
151 |
if ($fmt == Cryptor::FORMAT_B64) {
|
7 |
- |
152 |
$raw = base64_decode($in);
|
|
|
153 |
}
|
65 |
- |
154 |
else if ($fmt == Cryptor::FORMAT_HEX) {
|
7 |
- |
155 |
$raw = pack('H*', $in);
|
|
|
156 |
}
|
|
|
157 |
// and do an integrity check on the size.
|
65 |
- |
158 |
if (strlen($raw) < self::$iv_num_bytes) {
|
|
|
159 |
throw new \Exception('Cryptor::decryptString() - ' . 'data length ' . strlen($raw) . " is less than iv length {self::$iv_num_bytes}");
|
7 |
- |
160 |
}
|
|
|
161 |
// Extract the initialization vector and encrypted data
|
|
|
162 |
$iv = substr($raw, 0, self::$iv_num_bytes);
|
|
|
163 |
$raw = substr($raw, self::$iv_num_bytes);
|
|
|
164 |
// Hash the key
|
|
|
165 |
$keyhash = openssl_digest($key, self::$hash_algo, true);
|
|
|
166 |
// and decrypt.
|
|
|
167 |
$opts = OPENSSL_RAW_DATA;
|
|
|
168 |
$res = openssl_decrypt($raw, self::$cipher_algo, $keyhash, $opts, $iv);
|
65 |
- |
169 |
if ($res === false) {
|
7 |
- |
170 |
throw new \Exception('Cryptor::decryptString - decryption failed: ' . openssl_error_string());
|
|
|
171 |
}
|
|
|
172 |
return $res;
|
|
|
173 |
}
|
|
|
174 |
/**
|
|
|
175 |
* Static convenience method for encrypting.
|
|
|
176 |
* @param string $in String to encrypt.
|
|
|
177 |
* @param string $key Optional encryption key.
|
|
|
178 |
* @param int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
|
|
|
179 |
* @return string The encrypted string.
|
|
|
180 |
*/
|
65 |
- |
181 |
public static function Encrypt($in, $key = null, $fmt = null) {
|
7 |
- |
182 |
return self::encryptString($in, $key, $fmt);
|
|
|
183 |
}
|
|
|
184 |
/**
|
|
|
185 |
* Static convenience method for decrypting.
|
|
|
186 |
* @param string $in String to decrypt.
|
|
|
187 |
* @param string $key Optinal eecryption key.
|
|
|
188 |
* @param int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
|
|
|
189 |
* @return string The decrypted string.
|
|
|
190 |
*/
|
65 |
- |
191 |
public static function Decrypt($in, $key = null, $fmt = null) {
|
7 |
- |
192 |
return self::decryptString($in, $key, $fmt);
|
|
|
193 |
}
|
10 |
- |
194 |
}
|