RC4 RC4 is an encryption algorithm that was created by Ronald Rivets of RSA Security. It is used in WE and WA! WA! which are ar e encryption protocols commonly used on wireless routers. "he wor#ings of RC4 used to be a secret! but its code was lea#ed onto the internet in $%%4. RC4 was originally very widely used due to its simplicity and speed. "ypically "ypically $& byte #eys are used for strong encryption! but shorter #ey lengths are also widely used due to e'port restrictions. (ver "ime this code was shown to produce biased outputs towards certain se)uences! mostly in first few bytes of the #ey stream generated. "his led to a future version of the RC4 code that is more widely used today! called called RC4*drop+n,! in which the first n bytes of the #ey stream are dropped in order to get rid of this biased output. Some notable uses of RC4 are implemented in -icrosoft E'cel! Adobes Acrobat Acrobat /.0 1$%%42! and 3it "orrent clients. "o begin the process of RC4 encryption! you need a #ey! which is often user* defined and between 40*bits and /&*bits. A 40*bit #ey represents a five character ASCII code that gets translated into its 40 character binary e)uivalent 1for e'ample! the ASCII #ey 5pwd$/5 is e)uivalent to 0$$$00000$$$0$$$0$$00$0000$$000$00$$00$0 in binary2. "he ne't part of RC4 is the #ey*scheduling algorithm 16SA2 Algorithm for 6SA7 for i from 0 to / S+i, 78 i endfor 9 78 0 for i from 0 to / 9 78 19 : S+i, : #ey+i mod #eylength,2 #eylength,2 mod /& swap1S+i,!S+9,2 endfor
import 9ava.io.;< class RC4 =
public static void main1String args+,2throws I(E'ception = int temp80< String pte't< String #ey< int s+,8new int+/&,< int #+,8new int+/&,< 3ufferedReader in8new 3ufferedReader1new InputStreamReader1System.in22< System.out.print15>nE?"ER @AI? "E">t52< pte't8in.read@ine12< System.out.print15>n>nE?"ER 6EB "E">t>t52< #ey8in.read@ine12< char pte'tc+,8pte't.toCharArray12< char #eyc+,8#ey.toCharArray12< int cipher+,8new int+pte't.length12,< int decrypt+,8new int+pte't.length12,< int pte'ti+,8new int+pte't.length12,< int #eyi+,8new int+#ey.length12,< for1int i80
int i80< 980< int F80< for1int l80n>nE?CRB"EH7>t>t52< display1cipher2< System.out.print15>n>nHECRB"EH7>t>t52< display1decrypt2< D static void display1int disp+,2 = char convert+,8new char+disp.length,< for1int l80
import 9ava.util.;< class HES = Initial ermutation table private static final byte+, I 8 = J! 0! 4/! K4! /&! $J! $0! /!
&0! /! 44! K&! /J! /0! $/! 4! &/! 4! 4&! KJ! K0! //! $4! &! &4! &! 4J! 40! K/! /4! $&! J! L! 4%! 4$! KK! /! $L! %! $! %! $! 4K! K! /L! $%! $$! K! &$! K! 4! KL! /%! /$! $K! ! &K! ! 4L! K%! K$! /K! $! L D< ermuted Choice $ table private static final byte+, C$ 8 = L! 4%! 4$! KK! /! $L! %! $! J! 0! 4/! K4! /&! $J! $0! /! %! $! 4K! K! /L! $%! $$! K! &0! /! 44! K&! &K! ! 4L! K%! K$! /K! $! L! &/! 4! 4&! KJ! K0! //! $4! &! &$! K! 4! KL! /%! /$! $K! ! /J! /0! $/! 4 D< ermuted Choice / table private static final byte+, C/ 8 = $4! $L! $$! /4! $! ! K! /J! $! &! /$! $0! /K! $%! $/! 4! /&! J! $&! L! /L! /0! $K! /! 4$! /! K$! KL! 4L! ! K0! 40! $! 4! KK! 4J! 44! 4%! K%! &! K4! K! 4&! 4/! 0! K&! /%! K/ D< Array to store the number of rotations that are to be done on each round private static final byte+, rotations 8 = $! $! /! /! /! /! /! /! $! /! /! /! /! /! /! $ D< E'pansion 1a#a *bo'2 table private static final byte+, E 8 = K/! $! /! K! 4! !
4! ! &! L! J! %! J! %! $0! $$! $/! $K! $/! $K! $4! $! $&! $L! $&! $L! $J! $%! /0! /$! /0! /$! //! /K! /4! /! /4! /! /&! /L! /J! /%! /J! /%! K0! K$! K/! $ D< S*bo'es 1i.e. Substitution bo'es2 private static final byte+,+, S 8 = = $4! 4! $K! $! /! $! $$! J! K! $0! &! $/! ! %! 0! L! 0! $! L! 4! $4! /! $K! $! $0! &! $/! $$! %! ! K! J! 4! $! $4! J! $K! &! /! $$! $! $/! %! L! K! $0! ! 0! $! $/! J! /! 4! %! $! L! ! $$! K! $4! $0! 0! &! $K D! = $! $! J! $4! &! $$! K! 4! %! L! /! $K! $/! 0! ! $0! K! $K! 4! L! $! /! J! $4! $/! 0! $! $0! &! %! $$! ! 0! $4! L! $$! $0! 4! $K! $! ! J! $/! &! %! K! /! $! $K! J! $0! $! K! $! 4! /! $$! &! L! $/! 0! ! $4! % D! = $0! 0! %! $4! &! K! $! ! $! $K! $/! L! $$! 4! /! J! $K! L! 0! %! K! 4! &! $0! /! J! ! $4! $/! $$! $! $! $K! &! 4! %! J! $! K! 0! $$! $! /! $/! ! $0! $4! L! $! $0! $K! 0! &! %! J! L! 4! $! $4! K! $$! ! /! $/ D! = L! $K! $4! K! 0! &! %! $0! $! /! J! ! $$! $/! 4! $! $K! J! $$! ! &! $! 0! K! 4! L! /! $/! $! $0! $4! %! $0! &! %! 0! $/! $$! L! $K! $! $! K! $4! ! /! J! 4! K! $! 0! &! $0! $! $K! J! %! 4! ! $$! $/! L! /! $4 D! = /! $/! 4! $! L! $0! $$! &! J! ! K! $! $K! 0! $4! %! $4! $$! /! $/! 4! L! $K! $! ! 0! $! $0! K! %! J! &! 4! /! $! $$! $0! $K! L! J! $! %! $/! ! &! K! 0! $4! $$! J! $/! L! $! $4! /! $K! &! $! 0! %! $0! 4! ! K D! = $/! $! $0! $! %! /! &! J! 0! $K! K! 4! $4! L! ! $$! $0! $! 4! /! L! $/! %! ! &! $! $K! $4! 0! $$! K! J! %! $4! $! ! /! J! $/! K! L! 0! 4! $0! $! $K! $$! &! 4! K! /! $/! %! ! $! $0! $$! $4! $! L! &! 0! J! $K
D! = 4! $$! /! $4! $K! 0! $$! L! $! 4! $$! $K! &! $$! $K! J!
$! 0! J! $K! K! $/! %! L! ! $0! &! $! 4! %! $! $0! $4! K! ! $/! /! $! J! &! $/! K! L! $4! $0! $! &! J! 0! ! %! /! $! 4! $0! L! %! ! 0! $! $4! /! K! $/
D! = $K! /! J! 4! &! $! $$! $! $0! %! K! $4! ! 0! $/! L! $! $! $K! J! $0! K! L! 4! $/! ! &! $$! 0! $4! %! /! L! $$! 4! $! %! $/! $4! /! 0! &! $0! $K! $! K! ! J! /! $! $4! L! 4! $0! J! $K! $! $/! %! 0! K! ! &! $$ D D< ermutation table private static final byte+, 8 = $&! L! /0! /$! /%! $/! /J! $L! $! $! /K! /&! ! $J! K$! $0! /! J! /4! $4! K/! /L! K! %! $%! $K! K0! &! //! $$! 4! / D< Minal permutation 1a#a Inverse permutation2 table private static final byte+, M 8 = 40! J! 4J! $&! &! /4! &4! K/! K%! L! 4L! $! ! /K! &K! K$! KJ! &! 4&! $4! 4! //! &/! K0! KL! ! 4! $K! K! /$! &$! /%! K&! 4! 44! $/! /! /0! &0! /J! K! K! 4K! $$! $! $%! %! /L! K4! /! 4/! $0! 0! $J! J! /&! KK! $! 4$! %! 4%! $L! L! / D< /J bits each! used as storage in the 6S 16ey Structure2 rounds to generate round #eys 1a#a sub#eys2 private static int+, C 8 new int+/J,< private static int+, H 8 new int+/J,<
Hecryption re)uires the $& sub#eys to be used in the e'act same process as encryption! with the only difference being that the #eys are used in reverse order! i.e. last #ey is used first and so on. Nence! during encryption when the #eys are first generated! they are stored in this array. In case we wish to separate the encryption and decryption programs! then we need to generate the sub#eys first in order! store them and then use them in reverse order. private static int+,+, sub#ey 8 new int+$&,+4J,< public static void main1String args+,2 = System.out.println15Enter the input as a $& character he'adecimal value752< String input 8 new Scanner1System.in2.ne't@ine12< int input3its+, 8 new int+&4,< input3its will store the &4 bits of the input as a an int array of siFe &4. "his program uses int arrays to store bits! for the sa#e of simplicity. Mor efficient programming! use long data type. 3ut it increases program comple'ity which is unnecessary for this conte't. for1int i80 < i $& < i::2 = Mor every character in the $& bit input! we get its binary value by first parsing it into an int and then converting to a binary string String s 8 Integer.to3inaryString1Integer.parseInt1input.charAt1i2 : 55! $&22< Oava does not add padding Feros! i.e. is returned as $$$ but we re)uire 0$$$. Nence! this while loop adds padding 0s to the binary value. while1s.length12 42 = s 8 505 : s< D Add the 4 bits we have e'tracted into the array of bits. for1int 980 < 9 4 < 9::2 = input3its+14;i2:9, 8 Integer.parseInt1s.charAt192 : 552< D D Similar process is followed for the $& bit #ey
System.out.println15Enter the #ey as a $& character he'adecimal value752< String #ey 8 new Scanner1System.in2.ne't@ine12< int #ey3its+, 8 new int+&4,< for1int i80 < i $& < i::2 = String s 8 Integer.to3inaryString1Integer.parseInt1#ey.charAt1i2 : 55! $&22< while1s.length12 42 = s 8 505 : s< D for1int 980 < 9 4 < 9::2 = #ey3its+14;i2:9, 8 Integer.parseInt1s.charAt192 : 552< D D permute1int+, input3its! int+, #ey3its! boolean isHecrypt2 method is used here. "his allows encryption and decryption to be done in the same method! reducing code. System.out.println15>n::: E?CRB"I(? :::52< int output3its+, 8 permute1input3its! #ey3its! false2< System.out.println15>n::: HECRB"I(? :::52< permute1output3its! #ey3its! true2< D private static int+, permute1int+, input3its! int+, #ey3its! boolean isHecrypt2 = Initial permutation step ta#es input bits and permutes into the new3its array int new3its+, 8 new int+input3its.length,< for1int i80 < i input3its.length < i::2 = new3its+i, 8 input3its+I+i,*$,< D $& rounds will start here @ and R arrays are created to store the @eft and Right halves of the sub#ey respectively int @+, 8 new int+K/,< int R+, 8 new int+K/,< int i<
ermuted Choice $ is done here for1i80 < i /J < i::2 = C+i, 8 #ey3its+C$+i,*$,< D for1 < i & < i::2 = H+i*/J, 8 #ey3its+C$+i,*$,< D After C$ the first @ and R are ready to be used and hence looping can start once @ and R are initialiFed System.arraycopy1new3its! 0! @! 0! K/2< System.arraycopy1new3its! K/! R! 0! K/2< System.out.print15>n@0 8 52< display3its1@2< System.out.print15R0 8 52< display3its1R2< for1int n80 < n $& < n::2 = System.out.println15>n*************52< System.out.println15Round 5 : 1n:$2 : 5752< newR is the new R half generated by the Miestel function. If it is encrpytion then the 6S method is called to generate the sub#ey otherwise the stored sub#eys are used in reverse order for decryption. int newR+, 8 new int+0,< if1isHecrypt2 = newR 8 fiestel1R! sub#ey+$*n,2< System.out.print15Round #ey 8 52< display3its1sub#ey+$*n,2< D else = newR 8 fiestel1R! 6S1n! #ey3its22< System.out.print15Round #ey 8 52< display3its1sub#ey+n,2< D 'or*ing the @ and new R gives the new @ value. new @ is stored in R and new R is stored in @! thus e'changing R and @ for the ne't round. int new@+, 8 'or1@! newR2< @ 8 R<
R 8 new@< System.out.print15@ 8 52< display3its1@2< System.out.print15R 8 52< display3its1R2< D R and @ has the two halves of the output before applying the final permutation. "his is called the 5reoutput5. int output+, 8 new int+&4,< System.arraycopy1R! 0! output! 0! K/2< System.arraycopy1@! 0! output! K/! K/2< int final(utput+, 8 new int+&4,< Applying M table to the preoutput! we get the final output7 Encryption 8P final output is cipherte't Hecryption 8P final output is plainte't for1i80 < i &4 < i::2 = final(utput+i, 8 output+M+i,*$,< D Since the final output is stored as an int array of bits! we convert it into a he' string7 String he' 8 new String12< for1i80 < i $& < i::2 = String bin 8 new String12< for1int 980 < 9 4 < 9::2 = bin :8 final(utput+14;i2:9,< D int decimal 8 Integer.parseInt1bin! /2< he' :8 Integer.toNe'String1decimal2< D if1isHecrypt2 = System.out.print15Hecrypted te't7 52< D else = System.out.print15Encrypted te't7 52< D System.out.println1he'.toQpperCase122< return final(utput< D
private static int+, 6S1int round! int+, #ey2 = "he 6S 16ey Structure2 function generates the round #eys. C$ and H$ are the new values of C and H which will be generated in this round. int C$+, 8 new int+/J,< int H$+, 8 new int+/J,< "he rotation array is used to set how many rotations are to be done int rotation"imes 8 1int2 rotations+round,< leftShift12 method is used for rotation 1the rotation is basically2 a left shift operation! hence the name. C$ 8 leftShift1C! rotation"imes2< H$ 8 leftShift1H! rotation"imes2< CnHn stores the combined C$ and H$ halves int CnHn+, 8 new int+&,< System.arraycopy1C$! 0! CnHn! 0! /J2< System.arraycopy1H$! 0! CnHn! /J! /J2< 6n stores the sub#ey! which is generated by applying the C/ table to CnHn int 6n+, 8 new int+4J,< for1int i80 < i 6n.length < i::2 = 6n+i, 8 CnHn+C/+i,*$,< D ?ow we store C$ and H$ in C and H respectively! thus becoming the old C and H for the ne't round. Sub#ey is stored and returned. sub#ey+round, 8 6n< C 8 C$< H 8 H$< return 6n< D private static int+, fiestel1int+, R! int+, round6ey2 = -ethod to implement Miestel function. Mirst the K/ bits of the R array are e'panded using E table. int e'pandedR+, 8 new int+4J,< for1int i80 < i 4J < i::2 = e'pandedR+i, 8 R+E+i,*$,<
D We 'or the e'panded R and the generated round #ey int temp+, 8 'or1e'pandedR! round6ey2< "he S bo'es are then applied to this 'or result and this is the output of the Miestel function. int output+, 8 s3loc#1temp2< return output< D private static int+, 'or1int+, a! int+, b2 = Simple 'or function on two int arrays int answer+, 8 new int+a.length,< for1int i80 < i a.length < i::2 = answer+i, 8 a+i,Gb+i,< D return answer< D private static int+, s3loc#1int+, bits2 = S*bo'es are applied in this method. int output+, 8 new int+K/,< We #now that input will be of K/ bits! hence we will loop K/4 8 J times 1divided by 4 as we will ta#e 4 bits of input at each iteration2. for1int i80 < i J < i::2 = S*bo' re)uires a row and a column! which is found from the input bits. "he first and &th bit of the current iteration 1i.e. bits 0 and 2 gives the row bits. int row+, 8 new int +/,< row+0, 8 bits+&;i,< row+$, 8 bits+1&;i2:,< String sRow 8 row+0, : 55 : row+$,< Similarly column bits are found! which are the 4 bits between the two row bits 1i.e. bits $!/!K!42 int column+, 8 new int+4,< column+0, 8 bits+1&;i2:$,< column+$, 8 bits+1&;i2:/,< column+/, 8 bits+1&;i2:K,< column+K, 8 bits+1&;i2:4,<
String sColumn 8 column+0, :55: column+$, :55: column+/, :55: column+K,< Converting binary into decimal value! to be given into the array as input int iRow 8 Integer.parseInt1sRow! /2< int iColumn 8 Integer.parseInt1sColumn! /2< int ' 8 S+i,+1iRow;$&2 : iColumn,< We get decimal value of the S*bo' here! but we need to convert it into binary7 String s 8 Integer.to3inaryString1'2< adding is re)uired since Oava returns a decimal as $$$ in binary! when we re)uire 0$$$. while1s.length12 42 = s 8 505 : s< D "he binary bits are appended to the output for1int 980 < 9 4 < 9::2 = output+1i;42 : 9, 8 Integer.parseInt1s.charAt192 : 552< D D table is applied to the output and this is the final output of one S*bo' round7 int final(utput+, 8 new int+K/,< for1int i80 < i K/ < i::2 = final(utput+i, 8 output++i,*$,< D return final(utput< D private static int+, leftShift1int+, bits! int n2 = @eft shifting ta#es place here! i.e. each bit is rotated to the left and the leftmost bit is stored at the rightmost bit. "his is a left shift operation. int answer+, 8 new int+bits.length,< System.arraycopy1bits! 0! answer! 0! bits.length2< for1int i80 < i n < i::2 = int temp 8 answer+0,< for1int 980 < 9 bits.length*$ < 9::2 = answer+9, 8 answer+9:$,<
D answer+bits.length*$, 8 temp< D return answer< D private static void display3its1int+, bits2 = -ethod to display int array bits as a he'adecimal string. for1int i80 < i bits.length < i:842 = String output 8 new String12< for1int 980 < 9 4 < 9::2 = output :8 bits+i:9,< D System.out.print1Integer.toNe'String1Integer.parseInt1output! /222< D System.out.println12< D D