· 7 years ago · Jan 22, 2019, 01:22 PM
1#!/usr/bin/perl
2#
3# RC4 Simple FILE Encryption/Decryption
4#
5# Copyright 2018 (c) Todor Donev
6# <todor.donev at gmail.com>
7# https://ethical-hacker.org/
8# https://facebook.com/ethicalhackerorg
9#
10# Description:
11# RC4 generates a pseudorandom stream of bits
12# (a keystream). As with any stream cipher,
13# these can be used for encryption by combining
14# it with the plaintext using bit-wise exclusive-or;
15# decryption is performed the same way (since
16# exclusive-or with given data is an involution).
17# (This is similar to the Vernam cipher except
18# that generated pseudorandom bits, rather than a
19# prepared stream, are used.) To generate the
20# keystream, the cipher makes use of a secret
21# internal state which consists of two parts:
22#
23# o A permutation of all 256 possible bytes
24# (denoted "S" below).
25#
26# o Two 8-bit index-pointers (denoted "i" and "j").
27#
28# The permutation is initialized with a variable
29# length key, typically between 40 and 2048 bits,
30# using the key-scheduling algorithm (KSA). Once
31# this has been completed, the stream of bits is
32# generated using the pseudo-random generation
33# algorithm (PRGA).
34#
35# [todor@paladium ~]$ perl rc4file.pl ethack test.txt test.rc4
36# [ RC4 Simple FILE Encryption/Decryption
37# [ =======
38# [ Author: Todor Donev <todor.donev at gmail.com>
39# [ https://ethical-hacker.org/
40# [ https://fb.com/ethicalhackerorg
41# [ =======
42# [ Opening test.txt
43# [ Calculation..
44# [ Ready and test.rc4 file is closed.
45# [todor@paladium ~]$ perl rc4file.pl ethack test.rc4 test.rc4.encoded.txt && cat test.rc4.encoded.txt
46# [ RC4 Simple FILE Encryption/Decryption
47# [ =======
48# [ Author: Todor Donev <todor.donev at gmail.com>
49# [ https://ethical-hacker.org/
50# [ https://fb.com/ethicalhackerorg
51# [ =======
52# [ Opening test.rc4
53# [ Calculation..
54# [ Ready and test.rc4.encoded.txt file is closed.
55# Ethical Hacker Bulgaria 2018
56# International Cybersecurity Association
57# [todor@paladium ~]$
58#
59# Disclaimer:
60# This or previous programs is for Educational
61# purpose ONLY. Do not use it without permission.
62# The usual disclaimer applies, especially the
63# fact that Todor Donev is not liable for any
64# damages caused by direct or indirect use of the
65# information or functionality provided by these
66# programs. The author or any Internet provider
67# bears NO responsibility for content or misuse
68# of these programs or any derivatives thereof.
69# By using these programs you accept the fact
70# that any damage (dataloss, system crash,
71# system compromise, etc.) caused by the use
72# of these programs is not Todor Donev's
73# responsibility.
74#
75# Use them at your own risk!
76
77use warnings;
78use strict;
79use open ':std', ':encoding(UTF-8)';
80
81print "[ RC4 Simple FILE Encryption/Decryption\n";
82print "[ =======\n";
83print "[ Author: Todor Donev <todor.donev at gmail.com>\n";
84print "[ https://ethical-hacker.org/\n";
85print "[ https://fb.com/ethicalhackerorg\n";
86print "[ =======\n";
87die "[ Usage: $0 <passphrase> <input file> <output file>\n" if(@ARGV != 3);
88our $MAX_CHUNK_SIZE = 1024 unless $MAX_CHUNK_SIZE;
89my $passphrase = $ARGV[0];
90print "[ Opening $ARGV[1]\n";
91open(IN, $ARGV[1]) or die "[ Error: Can't read $ARGV[1]: $!\n";
92die "[ Error: The file is empty" if (-z $ARGV[1]);
93open(OUT, ">$ARGV[2]") or die "[ Error: Can't wrote $ARGV[2]: $!\n";
94binmode(IN);
95binmode(OUT);
96print "[ Calculation..\n";
97my $bytes = (stat $ARGV[1])[7];
98while(sysread(IN,my $in,$bytes)){
99 print OUT rc4($passphrase, $in);
100}
101print "[ Ready and $ARGV[2] file is closed.\n";
102close(IN);
103close(OUT);
104
105sub rc4 {
106 my $self;
107 my(@state, $x, $y);
108 if (ref $_[0]){
109 $self = shift;
110 @state = @{$self->{state}};
111 $x = $self->{x};
112 $y = $self->{y};
113 } else {
114 @state = init(shift);
115 $x = $y = 0;
116 }
117 my $message = shift;
118 my $num_pieces = do{
119 my $num = length($message) / $MAX_CHUNK_SIZE;
120 my $int = int $num;
121 $int == $num ? $int : $int+1;
122 };
123 for my $piece (0..$num_pieces-1){
124 my @message = unpack "C*", substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE);
125 for ( @message ) {
126 $x = 0 if ++$x > 255;
127 $y -= 256 if ($y += $state[$x]) > 255;
128 @state[$x, $y] = @state[$y, $x];
129 $_ ^= $state[($state[$x]+$state[$y]) % 256];
130 }
131 substr($message, $piece * $MAX_CHUNK_SIZE, $MAX_CHUNK_SIZE) = pack "C*", @message;
132 }
133 if ($self) {
134 $self->{state} = \@state;
135 $self->{x} = $x;
136 $self->{y} = $y;
137 }
138 $message;
139}
140
141sub init {
142 my @k = unpack('C*',shift);
143 my @state = 0..255;
144 my $y = 0;
145 for my $x (0..255){
146 $y = ($k[$x % @k]+$state[$x]+$y) % 256;
147 @state[$x, $y] = @state[$y, $x];
148 }
149 wantarray ? @state : \@state;
150}