1
################################################################################
4
# an object oriented module implementing CipherSaber-1 and CS-2
7
# copyright (c) 2001 chromatic. All rights reserved.
8
# This program is free software; you can distribute and modify it under the
9
# same terms as Perl itself.
10
################################################################################
12
package Crypt::CipherSaber;
16
use vars qw($VERSION);
24
# CS-2 shuffles the state array N times, CS-1 once
26
if (!(defined $N) or ($N < 1)) {
29
my $self = [ $key, [ 0 .. 255 ], $N ];
36
$self->_setup_key($iv);
38
my $state = $self->[1];
39
my $output = _do_crypt($state, $message);
40
$self->[1] = [ 0 .. 255 ];
46
my $iv = $self->_gen_iv();
47
return $iv . $self->crypt($iv, @_);
52
my ($iv, $message) = unpack("a10a*", +shift);
53
return $self->crypt($iv, $message);
58
my ($in, $out, $iv) = @_;
60
unless(UNIVERSAL::isa($in, 'GLOB') and UNIVERSAL::isa($out, 'GLOB')) {
61
carp "I need filehandles!";
67
unless (length($iv) > 1) {
68
$iv = $self->_gen_iv();
70
$self->_setup_key($iv);
74
my $state = $self->[1];
80
($iv, $_) = unpack("a10a*", $_);
81
$self->_setup_key($iv);
84
($line, $state, @vars) = _do_crypt($state, $_, @vars);
87
$self->[1] = [ 0 .. 255 ];
99
$iv .= chr(int(rand(255)));
106
my $key = $self->[0] . shift;
107
my @key = map { ord } split(//, $key);
108
my $state = $self->[1];
112
# repeat N times, for CS-2
113
for (1 .. $self->[2]) {
114
for my $i (0 .. 255) {
115
$j += ($state->[$i] + ($key[$i % $length]));
117
(@$state[$i, $j]) = (@$state[$j, $i]);
123
my ($state, $message, $i, $j, $n) = @_;
127
for (0 .. (length($message) - 1 )) {
132
@$state[$i, $j] = @$state[$j, $i];
133
$n = $state->[$i] + $state->[$j];
135
$output .= chr( $state->[$n] ^ ord(substr($message, $_, 1)) );
138
return wantarray ? ($output, $state, $i, $j, $n) : $output;
147
Crypt::CipherSaber - Perl module implementing CipherSaber encryption.
151
use Crypt::CipherSaber;
152
my $cs = Crypt::CipherSaber->new('my pathetic secret key');
154
my $coded = $cs->encrypt('Here is a secret message for you');
155
my $decoded = $cs->decrypt($coded);
157
# encrypt from and to a file
158
open(INFILE, 'secretletter.txt') or die "Can't open infile: $!";
159
open(OUTFILE, '>secretletter.cs1') or die "Can't open outfile: $!";
162
$cs->fh_crypt(\*INFILE, \*OUTFILE, 1);
164
# decrypt from and to a file
165
open(INFILE, 'secretletter.cs1') or die "Can't open infile: $!";
166
open(OUTFILE, '>secretletter.txt') or die "Can't open outfile: $!";
169
$cs->fh_crypt(\*INFILE, \*OUTFILE);
173
The Crypt::CipherSaber module implements CipherSaber encryption, described at
174
http://ciphersaber.gurus.com. It is simple, fairly speedy, and relatively
175
secure algorithm based on RC4.
177
Encryption and decryption are done based on a secret key, which must be shared
178
with all intended recipients of a message.
184
=item B<new($key, $N)>
186
Initialize a new Crypt::CipherSaber object. $key, the key used to encrypt or to
187
decrypt messages is required. $N is optional. If provided and greater than
188
one, it will implement CipherSaber-2 encryption (slightly slower but more
189
secure). If not specified, or equal to 1, the module defaults to CipherSaber-1
190
encryption. $N must be a positive integer greater than one.
192
=item B<encrypt($message)>
194
Encrypt a message. This uses the key stored in the current Crypt::CipherSaber
195
object. It will generate a 10-byte random IV (Initialization Vector)
196
automatically, as defined in the RC4 specification. This returns a string
197
containing the encrypted message.
199
Note that the encrypted message may contain unprintable characters, as it uses
200
the extended ASCII character set (valid numbers 0 through 255).
202
=item B<decrypt($message)>
204
Decrypt a message. For the curious, the first ten bytes of an encrypted
205
message are the IV, so this must strip it off first. This returns a string
206
containing the decrypted message.
208
The decrypted message may also contain unprintable characters, as the
209
CipherSaber encryption scheme can handle binary files with fair ease. If this
210
is important to you, be sure to treat the results correctly.
212
=item B<crypt($iv, $message)>
214
If you wish to generate the IV with a more cryptographically secure random
215
string (at least compared to Perl's builtin rand() function), you may do so
216
separately, passing it to this method directly. The IV must be a ten-byte
217
string consisting of characters from the extended ASCII set.
219
This is generally only useful for encryption, although you may extract the
220
first ten characters of an encrypted message and pass them in yourself. You
221
might as well call B<decrypt()>, though. The more random the IV, the stronger
222
the encryption tends to be. On some operating systems, you can read from
223
/dev/random. Other approaches are the Math::TrulyRandom module, or compressing
224
a file, removing the headers, and compressing it again.
226
=item B<fh_crypt(\*INPUT, \*OUTPUT, ($iv))>
228
For the sake of efficiency, Crypt::CipherSaber can now operate on filehandles.
229
It's not super brilliant, but it's relatively fast and sane. Pass in a
230
reference to the input file handle and the output filehandle. If your platform
231
needs to use C<binmode()>, this is your responsibility. It is also your
232
responsibility to close the files.
234
You may also pass in an optional third parameter, an IV. There are three
235
possibilities here. If you pass no IV, C<fh_crypt()> will pull the first ten
236
bytes from *INPUT and use that as an IV. This corresponds to decryption. If
237
you pass in an IV of your own (generally ten digits, but more than one digits
238
as the code is now), it will use your own IV when encrypting the file. If you
239
pass in the value '1', it will generate a new, random IV for you. This
240
corresponds to an encryption.
246
chromatic <chromatic@wgz.org>
248
thanks to jlp for testing, moral support, and never fearing the icky details and to the fine folks at http://perlmonks.org
250
Additional thanks to Olivier Salaun and the Sympa project (http://www.sympa.org)
255
the CipherSaber home page at http://ciphersaber.gurus.com