| |
"Java & Stream Ciphers"
Vol. 8, Issue 10, p. 49
Listing 1
protected void engineInit( int i, SecureRandom _securerandom ) {
if ( ( i % 8 != 0 ) || ( i < 8 ) || ( i > 2048 ) )
throw new
InvalidParameterException(
"Keysize must be multiple of 8,and can only range from 32 to 448 (inclusive)" );
else {
keysize_ = i / 8;
engineInit( _securerandom );
return;
}
}
/**
* Method engineGenerateKey
* @return the RC4 Secret Key
*/
protected SecretKey engineGenerateKey() {
if ( random_ == null )
random_ = new SecureRandom();
// Create a temporary storage for the key
byte temp[] = new byte[keysize_];
// Randomly generate the key
random_.nextBytes( temp );
// Return a Key Spec with the Key and Key Type
return new SecretKeySpec( temp, "RC4" );
}
}
Listing 2
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" );
// Check key length
int len = userkey.length;
if ( len == 0 )
throw new InvalidKeyException(
"Invalid user key length" );
// Reset x and y
x = y = 0;
// Populate the the initial Sbox with 0 through 255
for ( int index = 0; index < 256; index++ )
sBox[index] = index;
// Initialize variables
int index1 = 0;
int index2 = 0;
int temp;
/* A temporary value will be taken from the 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 from 0 to 255.
* If the same key is passed through the Sbox, it will generate the same Sbox.
*/
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;
}
}
Listing 3
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;
/* 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 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] );
}
}
Listing 4
Cipher cipher =
Cipher.getInstance( "RC4", "RichWare" );
Cipher cipher2 =
Cipher.getInstance( "RC4", "RichWare" );
// Init the Cipher with Key, mode and random generator
cipher.init( Cipher.ENCRYPT_MODE, secretKey, _random );
// Encrypt the message with the secret key.
byte[] encryptedMessage =
cipher.doFinal( messageBytes, 0, messageBytes.length );
// Init the Cipher2 with Key, mode and random generator
cipher2.init( Cipher.DECRYPT_MODE, secretKey, _random );
// Decrypt the message with the secret key.
byte[] decryptedMessage =
cipher2.doFinal( encryptedMessage, 0,
encryptedMessage.length );
String decryptedMessageString =
new String( decryptedMessage, "UTF8" );
/* Check that the decrypted message and the original
* message are the same.
*/
if ( decryptedMessageString.equals( message ) )
System.out.println( "\nTest succeeded." );
else
System.out.println( "\nTest failed." );
|
|