166 lines
4.8 KiB
Perl
166 lines
4.8 KiB
Perl
|
#--------------------------------------------------------------------#
|
||
|
# Crypt::RC4
|
||
|
# Date Written: 07-Jun-2000 04:15:55 PM
|
||
|
# Last Modified: 13-Dec-2001 03:33:49 PM
|
||
|
# Author: Kurt Kincaid (sifukurt@yahoo.com)
|
||
|
# Copyright (c) 2001, Kurt Kincaid
|
||
|
# All Rights Reserved.
|
||
|
#
|
||
|
# This is free software and may be modified and/or
|
||
|
# redistributed under the same terms as Perl itself.
|
||
|
#--------------------------------------------------------------------#
|
||
|
|
||
|
package Crypt::RC4;
|
||
|
|
||
|
use strict;
|
||
|
use vars qw( $VERSION @ISA @EXPORT $MAX_CHUNK_SIZE );
|
||
|
|
||
|
$MAX_CHUNK_SIZE = 1024 unless $MAX_CHUNK_SIZE;
|
||
|
|
||
|
require Exporter;
|
||
|
|
||
|
@ISA = qw(Exporter);
|
||
|
@EXPORT = qw(RC4);
|
||
|
$VERSION = '2.02';
|
||
|
|
||
|
sub new {
|
||
|
my ( $class, $key ) = @_;
|
||
|
my $self = bless {}, $class;
|
||
|
$self->{state} = Setup( $key );
|
||
|
$self->{x} = 0;
|
||
|
$self->{y} = 0;
|
||
|
$self;
|
||
|
}
|
||
|
|
||
|
sub RC4 {
|
||
|
my $self;
|
||
|
my( @state, $x, $y );
|
||
|
if ( ref $_[0] ) {
|
||
|
$self = shift;
|
||
|
@state = @{ $self->{state} };
|
||
|
$x = $self->{x};
|
||
|
$y = $self->{y};
|
||
|
} else {
|
||
|
@state = Setup( shift );
|
||
|
$x = $y = 0;
|
||
|
}
|
||
|
my $message = shift;
|
||
|
my $num_pieces = do {
|
||
|
my $num = length($message) / $MAX_CHUNK_SIZE;
|
||
|
my $int = int $num;
|
||
|
$int == $num ? $int : $int+1;
|
||
|
};
|
||
|
for my $piece ( 0..$num_pieces - 1 ) {
|
||
|
my @message = unpack "C*", substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE);
|
||
|
for ( @message ) {
|
||
|
$x = 0 if ++$x > 255;
|
||
|
$y -= 256 if ($y += $state[$x]) > 255;
|
||
|
@state[$x, $y] = @state[$y, $x];
|
||
|
$_ ^= $state[( $state[$x] + $state[$y] ) % 256];
|
||
|
}
|
||
|
substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE) = pack "C*", @message;
|
||
|
}
|
||
|
if ($self) {
|
||
|
$self->{state} = \@state;
|
||
|
$self->{x} = $x;
|
||
|
$self->{y} = $y;
|
||
|
}
|
||
|
$message;
|
||
|
}
|
||
|
|
||
|
sub Setup {
|
||
|
my @k = unpack( 'C*', shift );
|
||
|
my @state = 0..255;
|
||
|
my $y = 0;
|
||
|
for my $x (0..255) {
|
||
|
$y = ( $k[$x % @k] + $state[$x] + $y ) % 256;
|
||
|
@state[$x, $y] = @state[$y, $x];
|
||
|
}
|
||
|
wantarray ? @state : \@state;
|
||
|
}
|
||
|
|
||
|
|
||
|
1;
|
||
|
__END__
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
Crypt::RC4 - Perl implementation of the RC4 encryption algorithm
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
|
# Functional Style
|
||
|
use Crypt::RC4;
|
||
|
$encrypted = RC4( $passphrase, $plaintext );
|
||
|
$decrypt = RC4( $passphrase, $encrypted );
|
||
|
|
||
|
# OO Style
|
||
|
use Crypt::RC4;
|
||
|
$ref = Crypt::RC4->new( $passphrase );
|
||
|
$encrypted = $ref->RC4( $plaintext );
|
||
|
|
||
|
$ref2 = Crypt::RC4->new( $passphrase );
|
||
|
$decrypted = $ref2->RC4( $encrypted );
|
||
|
|
||
|
# process an entire file, one line at a time
|
||
|
# (Warning: Encrypted file leaks line lengths.)
|
||
|
$ref3 = Crypt::RC4->new( $passphrase );
|
||
|
while (<FILE>) {
|
||
|
chomp;
|
||
|
print $ref3->RC4($_), "\n";
|
||
|
}
|
||
|
|
||
|
=head1 DESCRIPTION
|
||
|
|
||
|
A simple implementation of the RC4 algorithm, developed by RSA Security, Inc. Here is the description
|
||
|
from RSA's website:
|
||
|
|
||
|
RC4 is a stream cipher designed by Rivest for RSA Data Security (now RSA Security). It is a variable
|
||
|
key-size stream cipher with byte-oriented operations. The algorithm is based on the use of a random
|
||
|
permutation. Analysis shows that the period of the cipher is overwhelmingly likely to be greater than
|
||
|
10100. Eight to sixteen machine operations are required per output byte, and the cipher can be
|
||
|
expected to run very quickly in software. Independent analysts have scrutinized the algorithm and it
|
||
|
is considered secure.
|
||
|
|
||
|
Based substantially on the "RC4 in 3 lines of perl" found at http://www.cypherspace.org
|
||
|
|
||
|
A major bug in v1.0 was fixed by David Hook (dgh@wumpus.com.au). Thanks, David.
|
||
|
|
||
|
=head1 AUTHOR
|
||
|
|
||
|
Kurt Kincaid (sifukurt@yahoo.com)
|
||
|
Ronald Rivest for RSA Security, Inc.
|
||
|
|
||
|
=head1 BUGS
|
||
|
|
||
|
Disclaimer: Strictly speaking, this module uses the "alleged" RC4
|
||
|
algorithm. The Algorithm known as "RC4" is a trademark of RSA Security
|
||
|
Inc., and this document makes no claims one way or another that this
|
||
|
is the correct algorithm, and further, make no claims about the
|
||
|
quality of the source code nor any licensing requirements for
|
||
|
commercial use.
|
||
|
|
||
|
There's nothing preventing you from using this module in an insecure
|
||
|
way which leaks information. For example, encrypting multilple
|
||
|
messages with the same passphrase may allow an attacker to decode all of
|
||
|
them with little effort, even though they'll appear to be secured. If
|
||
|
serious crypto is your goal, be careful. Be very careful.
|
||
|
|
||
|
It's a pure-Perl implementation, so that rating of "Eight
|
||
|
to sixteen machine operations" is good for nothing but a good laugh.
|
||
|
If encryption and decryption are a bottleneck for you, please re-write
|
||
|
this module to use native code wherever practical.
|
||
|
|
||
|
=head1 LICENSE
|
||
|
|
||
|
This is free software and may be modified and/or
|
||
|
redistributed under the same terms as Perl itself.
|
||
|
|
||
|
=head1 SEE ALSO
|
||
|
|
||
|
L<perl>, L<http://www.cypherspace.org>, L<http://www.rsasecurity.com>,
|
||
|
L<http://www.achtung.com/crypto/rc4.html>,
|
||
|
L<http://www.columbia.edu/~ariel/ssleay/rrc4.html>
|
||
|
|
||
|
=cut
|