Implementing the RC4 Stream Cipher

  

So far there has been a lot of discussion surrounding the block and asymmetric ciphers. The asymmetric cipher uses a key pair, while the block and stream ciphers use a secret key. The block ciphers encrypt a block and may require padding if the message is smaller than the block. The stream cipher doesn't require the padding because it may encrypt a bit or byte at a time.

One of the more popular stream encryptions is RC4 , which is discussed in this section. RC4 is a trademark of RSA, but the algorithm was made public on the Internet by an anonymous donor on the Cypherpunks mailing list in 1994. The discussion here is for educational purposes only to demonstrate what makes up a stream cipher. RC4 actually stands for Ron's Code number 4 (or Rivest's Cipher 4, Ron being Ron Rivest, the "R" in RSA).

Caution  

RC4 is used here for educational purposes only to demonstrate stream ciphers. Any commercial use of the algorithm must be arranged through RSA Data Security, Inc. at www.rsa.com . RC4 was made public on the Internet in 1994, and the algorithm has been distributed freely . This author wishes merely to demonstrate RC4 as a stream cipher for non-commercial purposes and educational purposes of understanding stream ciphers. It is the responsibility of the reader to arrange through RSA any use of RC4 for an organizational or personal use. RC4 is a trademark of RSA.

One of the characteristics of a stream cipher is not only the block size of 1 byte, but that one block will affect the encryption of the next block. A stream cipher is simply when one byte is XORed into the next byte, which is XORed into the next byte, and so on until the entire stream is encrypted. See Figure 13-2 for an example of an XORed byte stream.

click to expand
Figure 13-2: An XORed byte stream
Cross-Reference  

It is common for streams to have bytes XORed into the next byte in a stream cipher algorithm. See Chapter 3 for more information on XOR.

The previous discussion has given enough information to understand the basics of implementing a stream cipher as a service provider. The difference is that the block size will be 1 byte, and the padding and cipher operation mode will be null since a stream cipher does not have the same properties as a block cipher. Because the CipherSpi has already been discussed in detail, I will only mention some of the differences in this section. The biggest of these differences is the code that was published on the on the Cypherpunks mailing list. The RC4 algorithm is given in Listing 13-3.

Tip  

The examples from this book will be available at the companion Web site ( www. wiley .com/extras ).

Listing 13-3: The RC4 algorithm
start example
 /**    * Method rc4    * Description: performs encryption    * and decryption    *    * @param in the in buffer    * @param inOffset any in offset    * @param inLen the length of the in buffer    * @param out the out buffer    * @param outOffset any out offset    *    */   protected void rc4(byte[] in, int inOffset, int inLen,                   byte[] out, int outOffset)    {         /*      * The byte is XORed with the plaintext to produce the ciphertext      * The byte is XORed with the ciphertext to produce the plaintext      * The algorithm is symmetric, meaning this function will work for both      * encryption and decryption      */     int xorIndex, temp;         for (int i = 0; i < inLen; i++)      {       x                = (x + 1) & 0xFF;       y                = (sBox[x] + y) & 0xFF;       temp             = sBox[x];       sBox[x]          = sBox[y];       sBox[y]          = temp;       xorIndex         = (sBox[x] + sBox[y]) & 0xFF;       out[outOffset++] = (byte) (in[inOffset++]                                  ^ sBox[xorIndex]);     }   }       /**    * Method prepare_key    * Description: initializes the key    *    *    * @param key the key that will set the S-box.    *    * @throws InvalidKeyException    *    */   protected void prepare_key(Key key) throws InvalidKeyException    {         /*      * Fill the S-box with the key      * Key Setup      */     byte[] userkey = key.getEncoded();         if (userkey == null)      {       throw new InvalidKeyException("Null user key");     }         int len = userkey.length;         if (len == 0)      {       throw new InvalidKeyException(         "Invalid user key length");     }         /*      * Reset x and y      */     x = y = 0;         for (int index = 0; index < 256; index++)      {       sBox[index] = index;     }         int index1 = 0, index2 = 0, temp;         for (int counter = 0; counter < 256; counter++)      {       index2 =         ((userkey[index1] & 0xFF) + sBox[counter] + index2)         & 0xFF;           /*        * Swap the byte        */       temp          = sBox[counter];       sBox[counter] = sBox[index2];       sBox[index2]  = temp;       index1        = (index1 + 1) % len;     }   } } 
end example
 

Listing 13-3 lists the methods for the RC4 stream cipher algorithm. There are two main parts to the algorithm: the prepare_key that will set the S-boxes based on the key, and the RC4 method that will perform encryption and decryptions. An S-box is a substitution box, as discussed in Chapter 12. The RC4 does not do anything different for the encryption versus the decryption. The only difference is the input data. The key must remain the same for the encryption and decryption. The key for RC4 is a random byte array. To implement the key to the cipher engine as a service provider, a SPI implementation of the javax.crypto.KeyGeneratorSpi will have to be implemented that returns a javax.crytpo.SecretKey instance.

The SecretKey will be the key that is passed in the initialization of the engine cipher to be used for encryption and decryption. The key size of RC4 is variable. The key size can be from 1 byte to 256 bytes to match the S-boxes. The exporting regulations of the U.S. define that the maximum key size for exporting RC4 should not exceed 40 bits. The opmode that is normally passed in to determine whether the cipher engine is encrypting or decrypting wouldn't make a difference in this algorithm, because the only difference for encrypting and decrypting in RC4 is the input data.

When the key is passed into the RC4 engine cipher, it will be used to create the S-box. The S-box is an integer array containing 256 integers. The S-box offers 256 substitutions. These substitutions are permutations of the numbers 0 through 255. The permutations go through two steps. The first is to initialize the S-box 0 through 255, where S-Box[0] = 0, S-Box[1] = 1, and so on. After the S-boxes are initialized , they will be traversed again. A temporary value will be taken from an S-box that will be executed from 0 to 255. The key value is indexed from the length of the key. The S-box indexed from the counter will be swapped with the S-box indexed from the temporary value. The swapping will happen until all the S-boxes are walked through from 0 to 255.

Cross-Reference  

The S-boxes are discussed in Chapter 12.

Like most stream algorithms the encryption and decryption will be XORed through the byte stream. The text is processed one byte at a time. The RC4 method will work for both encrypting and decrypting. The RC4 method will generate to indexes. In Listing 13-3, the variables x and y are used for these indexes. Some algorithms will describe these variables as i and j . The x index is generated by adding to itself and finding the modulus ; the y index is done the same way and adds the S-box. The S-boxes that are indexed by x and y are swapped and then an XOR index value is found by adding the values in the S-boxes. The XOR index is used as an index for the S-box that will be XORed with the input byte. If the input byte is plaintext, it will return ciphertext. If the input byte is ciphertext, it will return plaintext.

Tip  

See http://www.ncat.edu/~grogans/main.htm for further information on RC4.

  


Java Security Solutions
Java Security Solutions
ISBN: 0764549286
EAN: 2147483647
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net