1 <?php
2 /**
3 * RSA Crypt
4 *
5 * Copyright (c) 2015, Dmitry Mamontov <d.slonyara@gmail.com>.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * Neither the name of Dmitry Mamontov nor the names of his
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * @package rsacrypt
38 * @author Dmitry Mamontov <d.slonyara@gmail.com>
39 * @copyright 2015 Dmitry Mamontov <d.slonyara@gmail.com>
40 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
41 * @since File available since Release 1.0.2
42 */
43
44 /**
45 * RsaCrypt - The main class
46 *
47 * @author Dmitry Mamontov <d.slonyara@gmail.com>
48 * @copyright 2015 Dmitry Mamontov <d.slonyara@gmail.com>
49 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
50 * @version Release: 1.0.2
51 * @link https://github.com/dmamontov/rsacrypt/
52 * @since Class available since Release 1.0.2
53 */
54 class RsaCrypt
55 {
56 /**
57 * Path to the keys.
58 * @var string
59 * @access protected
60 */
61 protected $private, $public;
62
63 /**
64 * Checks for the required functions for encryption.
65 * @return void
66 * @access public
67 * @final
68 */
69 final public function __construct()
70 {
71 if (
72 function_exists('openssl_get_publickey') === false ||
73 function_exists('openssl_public_encrypt') === false ||
74 function_exists('openssl_get_privatekey') === false ||
75 function_exists('openssl_private_decrypt') === false
76 ) {
77 throw new RuntimeException('Not all the functions of openssl.');
78 }
79 }
80
81 /**
82 * It generates private and public keys with the specified size.
83 * @param integer $size
84 * @return boolean
85 * @access public
86 * @final
87 */
88 final public function genKeys($size = 2048)
89 {
90 if (function_exists('exec') == false) {
91 throw new RuntimeException('Exec function not used.');
92 }
93 if (in_array($size, array(512, 1024, 2048)) === false) {
94 throw new RuntimeException('The key size can only be 512 bits, 1024 bits or 2048 bits. 2048 bits is recommended.');
95 }
96
97 @exec(
98 "openssl genrsa -out " .
99 __DIR__ . "/private.pem $size 2>&1 && openssl rsa -in " .
100 __DIR__ . "/private.pem -out " .
101 __DIR__ . "/public.pem -outform PEM -pubout 2>&1",
102 $out,
103 $status
104 );
105
106 if ($status == -1) {
107 throw new RuntimeException('Error generating keys. Check the settings for openssl.');
108 }
109
110 $this->public = 'public.pem';
111 $this->private = 'private.pem';
112
113 return true;
114 }
115
116 /**
117 * Initializes public key.
118 * @param string $key
119 * @return boolean
120 * @access public
121 * @final
122 */
123 final public function setPublicKey($key)
124 {
125 if (is_null($key) || empty($key) || file_exists($key) === false) {
126 throw new RuntimeException('Wrong key.');
127 }
128
129 $this->public = $key;
130
131 return true;
132 }
133
134 /**
135 * Gets public key.
136 * @return boolean
137 * @access public
138 * @final
139 */
140 final public function getPublicKey()
141 {
142 return is_null($this->public) ? false : $this->public;
143 }
144
145 /**
146 * Initializes private key.
147 * @param string $key
148 * @return mixed
149 * @access public
150 * @final
151 */
152 final public function setPrivateKey($key)
153 {
154 if (is_null($key) || empty($key) || file_exists($key) === false) {
155 throw new RuntimeException('Wrong key.');
156 }
157
158 $this->private = $key;
159
160 return true;
161 }
162
163 /**
164 * Gets private key.
165 * @return mixed
166 * @access public
167 * @final
168 */
169 final public function getPrivateKey()
170 {
171 return is_null($this->private) ? false : $this->private;
172 }
173
174 /**
175 * Data encryption.
176 * @param string $data
177 * @return mixed
178 * @access public
179 * @final
180 */
181 final public function encrypt($data)
182 {
183 if (is_null($data) || empty($data) || is_string($data) === false) {
184 throw new RuntimeException('Needless to encrypt.');
185 } elseif (is_null($this->public) || empty($this->public)) {
186 throw new RuntimeException('You need to set the public key.');
187 }
188
189 $key = @file_get_contents($this->public);
190 if ($key) {
191 $key = openssl_get_publickey($key);
192 openssl_public_encrypt($data, $encrypted, $key);
193
194 return chunk_split(base64_encode($encrypted));
195 }
196
197 return false;
198 }
199
200 /**
201 * Decrypt data.
202 * @param string $data
203 * @return mixed
204 * @access public
205 * @final
206 */
207 final public function decrypt($data)
208 {
209 if (is_null($data) || empty($data) || is_string($data) === false) {
210 throw new RuntimeException('Needless to encrypt.');
211 } elseif (is_null($this->private) || empty($this->private)) {
212 throw new RuntimeException('You need to set the private key.');
213 }
214
215 $key = @file_get_contents($this->private);
216 if ($key) {
217 $key = openssl_get_privatekey($key);
218 openssl_private_decrypt(base64_decode($data), $result, $key);
219
220 return reset($result);
221 }
222 }
223 }
224