yu.dong | c33b307 | 2024-08-21 23:14:49 -0700 | [diff] [blame^] | 1 | #--------------------------------------------------------------------# |
| 2 | # Crypt::RC4 |
| 3 | # Date Written: 07-Jun-2000 04:15:55 PM |
| 4 | # Last Modified: 13-Dec-2001 03:33:49 PM |
| 5 | # Author: Kurt Kincaid (sifukurt@yahoo.com) |
| 6 | # Copyright (c) 2001, Kurt Kincaid |
| 7 | # All Rights Reserved. |
| 8 | # |
| 9 | # This is free software and may be modified and/or |
| 10 | # redistributed under the same terms as Perl itself. |
| 11 | #--------------------------------------------------------------------# |
| 12 | |
| 13 | package Crypt::RC4; |
| 14 | |
| 15 | use strict; |
| 16 | use vars qw( $VERSION @ISA @EXPORT $MAX_CHUNK_SIZE ); |
| 17 | |
| 18 | $MAX_CHUNK_SIZE = 1024 unless $MAX_CHUNK_SIZE; |
| 19 | |
| 20 | require Exporter; |
| 21 | |
| 22 | @ISA = qw(Exporter); |
| 23 | @EXPORT = qw(RC4); |
| 24 | $VERSION = '2.02'; |
| 25 | |
| 26 | sub new { |
| 27 | my ( $class, $key ) = @_; |
| 28 | my $self = bless {}, $class; |
| 29 | $self->{state} = Setup( $key ); |
| 30 | $self->{x} = 0; |
| 31 | $self->{y} = 0; |
| 32 | $self; |
| 33 | } |
| 34 | |
| 35 | sub RC4 { |
| 36 | my $self; |
| 37 | my( @state, $x, $y ); |
| 38 | if ( ref $_[0] ) { |
| 39 | $self = shift; |
| 40 | @state = @{ $self->{state} }; |
| 41 | $x = $self->{x}; |
| 42 | $y = $self->{y}; |
| 43 | } else { |
| 44 | @state = Setup( shift ); |
| 45 | $x = $y = 0; |
| 46 | } |
| 47 | my $message = shift; |
| 48 | my $num_pieces = do { |
| 49 | my $num = length($message) / $MAX_CHUNK_SIZE; |
| 50 | my $int = int $num; |
| 51 | $int == $num ? $int : $int+1; |
| 52 | }; |
| 53 | for my $piece ( 0..$num_pieces - 1 ) { |
| 54 | my @message = unpack "C*", substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE); |
| 55 | for ( @message ) { |
| 56 | $x = 0 if ++$x > 255; |
| 57 | $y -= 256 if ($y += $state[$x]) > 255; |
| 58 | @state[$x, $y] = @state[$y, $x]; |
| 59 | $_ ^= $state[( $state[$x] + $state[$y] ) % 256]; |
| 60 | } |
| 61 | substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE) = pack "C*", @message; |
| 62 | } |
| 63 | if ($self) { |
| 64 | $self->{state} = \@state; |
| 65 | $self->{x} = $x; |
| 66 | $self->{y} = $y; |
| 67 | } |
| 68 | $message; |
| 69 | } |
| 70 | |
| 71 | sub Setup { |
| 72 | my @k = unpack( 'C*', shift ); |
| 73 | my @state = 0..255; |
| 74 | my $y = 0; |
| 75 | for my $x (0..255) { |
| 76 | $y = ( $k[$x % @k] + $state[$x] + $y ) % 256; |
| 77 | @state[$x, $y] = @state[$y, $x]; |
| 78 | } |
| 79 | wantarray ? @state : \@state; |
| 80 | } |
| 81 | |
| 82 | |
| 83 | 1; |
| 84 | __END__ |
| 85 | |
| 86 | =head1 NAME |
| 87 | |
| 88 | Crypt::RC4 - Perl implementation of the RC4 encryption algorithm |
| 89 | |
| 90 | =head1 SYNOPSIS |
| 91 | |
| 92 | # Functional Style |
| 93 | use Crypt::RC4; |
| 94 | $encrypted = RC4( $passphrase, $plaintext ); |
| 95 | $decrypt = RC4( $passphrase, $encrypted ); |
| 96 | |
| 97 | # OO Style |
| 98 | use Crypt::RC4; |
| 99 | $ref = Crypt::RC4->new( $passphrase ); |
| 100 | $encrypted = $ref->RC4( $plaintext ); |
| 101 | |
| 102 | $ref2 = Crypt::RC4->new( $passphrase ); |
| 103 | $decrypted = $ref2->RC4( $encrypted ); |
| 104 | |
| 105 | # process an entire file, one line at a time |
| 106 | # (Warning: Encrypted file leaks line lengths.) |
| 107 | $ref3 = Crypt::RC4->new( $passphrase ); |
| 108 | while (<FILE>) { |
| 109 | chomp; |
| 110 | print $ref3->RC4($_), "\n"; |
| 111 | } |
| 112 | |
| 113 | =head1 DESCRIPTION |
| 114 | |
| 115 | A simple implementation of the RC4 algorithm, developed by RSA Security, Inc. Here is the description |
| 116 | from RSA's website: |
| 117 | |
| 118 | RC4 is a stream cipher designed by Rivest for RSA Data Security (now RSA Security). It is a variable |
| 119 | key-size stream cipher with byte-oriented operations. The algorithm is based on the use of a random |
| 120 | permutation. Analysis shows that the period of the cipher is overwhelmingly likely to be greater than |
| 121 | 10100. Eight to sixteen machine operations are required per output byte, and the cipher can be |
| 122 | expected to run very quickly in software. Independent analysts have scrutinized the algorithm and it |
| 123 | is considered secure. |
| 124 | |
| 125 | Based substantially on the "RC4 in 3 lines of perl" found at http://www.cypherspace.org |
| 126 | |
| 127 | A major bug in v1.0 was fixed by David Hook (dgh@wumpus.com.au). Thanks, David. |
| 128 | |
| 129 | =head1 AUTHOR |
| 130 | |
| 131 | Kurt Kincaid (sifukurt@yahoo.com) |
| 132 | Ronald Rivest for RSA Security, Inc. |
| 133 | |
| 134 | =head1 BUGS |
| 135 | |
| 136 | Disclaimer: Strictly speaking, this module uses the "alleged" RC4 |
| 137 | algorithm. The Algorithm known as "RC4" is a trademark of RSA Security |
| 138 | Inc., and this document makes no claims one way or another that this |
| 139 | is the correct algorithm, and further, make no claims about the |
| 140 | quality of the source code nor any licensing requirements for |
| 141 | commercial use. |
| 142 | |
| 143 | There's nothing preventing you from using this module in an insecure |
| 144 | way which leaks information. For example, encrypting multilple |
| 145 | messages with the same passphrase may allow an attacker to decode all of |
| 146 | them with little effort, even though they'll appear to be secured. If |
| 147 | serious crypto is your goal, be careful. Be very careful. |
| 148 | |
| 149 | It's a pure-Perl implementation, so that rating of "Eight |
| 150 | to sixteen machine operations" is good for nothing but a good laugh. |
| 151 | If encryption and decryption are a bottleneck for you, please re-write |
| 152 | this module to use native code wherever practical. |
| 153 | |
| 154 | =head1 LICENSE |
| 155 | |
| 156 | This is free software and may be modified and/or |
| 157 | redistributed under the same terms as Perl itself. |
| 158 | |
| 159 | =head1 SEE ALSO |
| 160 | |
| 161 | L<perl>, L<http://www.cypherspace.org>, L<http://www.rsasecurity.com>, |
| 162 | L<http://www.achtung.com/crypto/rc4.html>, |
| 163 | L<http://www.columbia.edu/~ariel/ssleay/rrc4.html> |
| 164 | |
| 165 | =cut |