0: ############################################################
1: # Here's a module I'm packaging up for the CPAN.
2: # It implements the simple-yet-effective CipherSaber
3: # encryption scheme, levels one and two. Instructions are
4: # in the POD.
5: #
6: # If you have time, I'd appreciate a review and any
7: # recommendations. Thanks in advance.
8: ############################################################
9: package Crypt::CipherSaber;
10:
11: use strict;
12: use vars qw($VERSION);
13:
14: $VERSION = '0.02';
15:
16: sub new {
17: my $class = shift;
18: my $key = shift;
19:
20: # CS-2 shuffles the state array N times, CS-1 once
21: my $N = shift;
22: if (!(defined $N) or ($N < 1)) {
23: $N = 1;
24: }
25: my $self = [ $key, [ 0 .. 255 ], $N ];
26: bless($self, $class);
27: }
28:
29: sub crypt {
30: my $self = shift;
31: my $iv = shift;
32: $self->_setup_key($iv);
33: my $message = shift;
34: my $state = $self->[1];
35: my ($i, $j, $n) = (0, 0, 0);
36: my $output;
37: for (0 .. (length($message) -1 )) {
38: $i++;
39: $i %= 256;
40: $j += $state->[$i];
41: $j %= 256;
42: @$state[$i, $j] = @$state[$j, $i];
43: $n = $state->[$i] + $state->[$j];
44: $n %= 256;
45: $output .= chr( $state->[$n] ^ ord(substr($message, $_, 1)) );
46: }
47: $self->[1] = [ 0 .. 255 ];
48: return $output;
49: }
50:
51: sub encrypt {
52: my $self = shift;
53: my $iv = $self->_gen_iv();
54: return $iv . $self->crypt($iv, @_);
55: }
56:
57: sub decrypt {
58: my $self = shift;
59: my $message = shift;
60: my $iv = substr($message, 0, 10, '');
61: return $self->crypt($iv, $message);
62: }
63:
64: ###################
65: #
66: # PRIVATE METHODS
67: #
68: ###################
69: sub _gen_iv {
70: my $iv;
71: $iv .= chr(int(rand(255))) for (1 .. 10);
72: return $iv;
73: }
74:
75: sub _setup_key {
76: my $self = shift;
77: my $key = $self->[0] . shift;
78: my @key = map { ord } split(//, $key);
79: my $state = $self->[1];
80: my $j = 0;
81: my $length = @key;
82:
83: # repeat N times, for CS-2
84: for (1 .. $self->[2]) {
85: for my $i (0 .. 255) {
86: $j += ($state->[$i] + ($key[$i % $length]));
87: $j %= 256;
88: (@$state[$i, $j]) = (@$state[$j, $i]);
89: }
90: }
91: }
92:
93: 1;
94:
95: __END__
96:
97: =head1 NAME
98:
99: Crypt::CipherSaber - Perl module implementing CipherSaber encryption.
100:
101: =head1 SYNOPSIS
102:
103: use Crypt::CipherSaber;
104: my $cs = Crypt::CipherSaber->new('my pathetic secret key');
105:
106: my $coded = $cs->encrypt('Here is a secret message for you');
107: my $decoded = $cs->decrypt($coded);
108:
109: =head1 DESCRIPTION
110:
111: The Crypt::CipherSaber module implements CipherSaber encryption, described at
112: http://ciphersaber.gurus.com. It is simple, fairly speedy, and relatively
113: secure algorithm based on RC4.
114:
115: Encryption and decryption are done based on a secret key, which must be shared
116: with all intended recipients of a message.
117:
118: =head1 METHODS
119:
120: =item new($key, $N)
121:
122: Initialize a new Crypt::CipherSaber object. $key, the key used to encrypt or to
123: decrypt messages is required. $N is optional. If provided and greater than
124: one, it will implement CipherSaber-2 encryption (slightly slower but more
125: secure). If not specified, or equal to 1, the module defaults to CipherSaber-1
126: encryption. $N must be a positive integer greater than one.
127:
128: =item encrypt($message)
129:
130: Encrypt a message. This uses the key stored in the current Crypt::CipherSaber
131: object. It will generate a 10-byte random IV (Initialization Vector)
132: automatically, as defined in the RC4 specification. This returns a string
133: containing the encrypted message.
134:
135: Note that the encrypted message may contain unprintable characters, as it uses
136: the extended ASCII character set (valid numbers 0 through 255).
137:
138: =item decrypt($message)
139:
140: Decrypt a message. For the curious, the first ten bytes of an encrypted
141: message are the IV, so this must strip it off first. This returns a string
142: containing the decrypted message.
143:
144: The decrypted message may also contain unprintable characters, as the
145: CipherSaber encryption scheme can handle binary files with fair ease. If this
146: is important to you, be sure to treat the results correctly.
147:
148: =item crypt($iv, $message)
149:
150: If you wish to generate the IV with a more cryptographically secure random
151: string (at least compared to Perl's builtin rand() function), you may do so
152: separately, passing it to this method directly. The IV must be a ten-byte
153: string consisting of characters from the extended ASCII set.
154:
155: This is generally only useful for encryption, although you may extract the
156: first ten characters of an encrypted message and pass them in yourself. You
157: might as well call B<decrypt()>, though.
158:
159: =head1 AUTHOR
160:
161: chromatic <chromatic@wgz.org>
162:
163: thanks to jlp for testing and moral support, and to the fine
164: folks at http://perlmonks.org
165:
166: =head1 SEE ALSO
167:
168: the CipherSaber home page at http://ciphersaber.gurus.com
169:
170: perl(1), rand().
171:
172: =cut In reply to Crypt::CipherSaber by chromatic
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |