-
Notifications
You must be signed in to change notification settings - Fork 18
/
Cipher.php
257 lines (212 loc) · 6.88 KB
/
Cipher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<?php
/*
* Author: Ryan Gilfether
* URL: http://www.gilfether.com/phpCrypt
* Date: Sep 4, 2005
* Copyright (C) 2005 Ryan Gilfether
*
* This file is part of phpCrypt
*
* phpCrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
namespace PHP_Crypt;
require_once(dirname(__FILE__)."/Core.php");
require_once(dirname(__FILE__)."/phpCrypt.php");
/**
* Generic parent class for ciphers. Should not be used directly,
* instead a class should extend from this class
*
* @author Ryan Gilfether
* @link http://www.gilfether.com/phpcrypt
* @copyright 2005 Ryan Gilfether
*/
abstract class Cipher extends Core
{
/** @type integer ENCRYPT Indicates when we are in encryption mode */
const ENCRYPT = 1;
/** @type integer DECRYPT Indicates when we are in decryption mode */
const DECRYPT = 2;
/** @type integer BLOCK Indicates that a cipher is a block cipher */
const BLOCK = 1;
/** @type integer STREAM Indicates that a cipher is a stream cipher */
const STREAM = 2;
/** @type string $cipher_name Stores the name of the cipher */
protected $cipher_name = "";
/** @type integer $block_size The block size of the cipher in bytes */
protected $block_size = 0;
/**
* @type integer $operation Indicates if a cipher is Encrypting or Decrypting
* this can be set to either Cipher::ENCRYPT or Cipher::DECRYPT
*/
protected $operation = self::ENCRYPT; // can be either Cipher::ENCRYPT | Cipher::DECRYPT;
/** @type string $key Stores the key for the Cipher */
private $key = "";
/** @type integer $key_len Keep track of the key length, so we don't
have to make repeated calls to strlen() to find the length */
private $key_len = 0;
/**
* Constructor
*
* @param string $name one of the predefined ciphers
* @param string $key The key used for encryption
* @param int Optional, the required size of a key for the cipher
* @return void
*/
protected function __construct($name, $key = "", $required_key_sz = 0)
{
$this->name($name);
$this->key($key, $required_key_sz);
}
/**
* Destructor
*
* @return void
*/
protected function __destruct()
{
}
/**********************************************************************
* ABSTRACT METHODS
*
* The abstract methods required by inheriting classes to implement
**********************************************************************/
/**
* The cipher's encryption function. Must be defined
* by the class inheriting this Cipher object. This function
* will most often be called from within the Mode object
*
* @param string $text The text to be encrypted
* @return boolean Always returns false
*/
abstract public function encrypt(&$text);
/**
* The cipher's decryption function. Must be defined
* by the class inheriting this Cipher object. This function
* will most often be called from within the Mode object
*
* @param string $text The text to decrypt
* @return boolean Always returns false
*/
abstract public function decrypt(&$text);
/**
* Indiciates whether the cipher is a block or stream cipher
*
* @return integer Returns either Cipher::BLOCK or Cipher::STREAM
*/
abstract public function type();
/**********************************************************************
* PUBLIC METHODS
*
**********************************************************************/
/**
* Determine if we are Encrypting or Decrypting
* Since some ciphers use the same algorithm to Encrypt or Decrypt but with only
* slight differences, we need a way to check if we are Encrypting or Decrypting
* An example is DES, which uses the same algorithm except that when Decrypting
* the sub_keys are reversed
*
* @param integer $op Sets the operation to Cipher::ENCRYPT or Cipher::DECRYPT
* @return integer The current operation, either Cipher::ENCRYPT or Cipher::DECRYPT
*/
public function operation($op = 0)
{
if($op == self::ENCRYPT || $op == self::DECRYPT)
$this->operation = $op;
return $this->operation;
}
/**
* Return the name of cipher that is currently being used
*
* @return string The cipher name
*/
public function name($name = "")
{
if($name != "")
$this->cipher_name = $name;
return $this->cipher_name;
}
/**
* Size of the data in Bits that get used during encryption
*
* @param integer $bytes Number of bytes each block of data is required by the cipher
* @return integer The number of bytes each block of data required by the cipher
*/
public function blockSize($bytes = 0)
{
if($bytes > 0)
$this->block_size = $bytes;
// in some cases a blockSize is not set, such as stream ciphers.
// so just return 0 for the block size
if(!isset($this->block_size))
return 0;
return $this->block_size;
}
/**
* Returns the size (in bytes) required by the cipher.
*
* @return integer The number of bytes the cipher requires the key to be
*/
public function keySize()
{
return $this->key_len;
}
/**
* Set the cipher key used for encryption/decryption. This function
* may lengthen or shorten the key to meet the size requirements of
* the cipher.
*
* If the $key parameter is not given, this function simply returns the
* current key being used.
*
* @param string $key Optional, A key for the cipher
* @param integer $req_sz The byte size required for the key
* @return string They key, which may have been modified to fit size
* requirements
*/
public function key($key = "", $req_sz = 0)
{
if($key != "" && $key != null)
{
// in the case where the key is changed changed after
// creating a new Cipher object and the $req_sz was not
// given, we need to make sure the new key meets the size
// requirements. This can be determined from the $this->key_len
// member set from the previous key
if($this->key_len > 0 && $req_sz == 0)
$req_sz = $this->key_len;
else
$this->key_len = strlen($key);
if($req_sz > 0)
{
if($this->key_len > $req_sz)
{
// shorten the key length
$key = substr($key, 0, $req_sz);
$this->key_len = $req_sz;
}
else if($this->key_len < $req_sz)
{
// send a notice that the key was too small
// NEVER PAD THE KEY, THIS WOULD BE INSECURE!!!!!
$msg = strtoupper($this->name())." requires a $req_sz byte key, {$this->key_len} bytes received";
trigger_error($msg, E_USER_WARNING);
return false;
}
}
$this->key = $key;
}
return $this->key;
}
}
?>