⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rc4.java

📁 面向应用的智能安全代理平台和工具包是一个综合网络应用的安全共性需求而设计和实现的一个通用性的网络信息安全应用支撑平台
💻 JAVA
字号:
package au.net.aba.crypto.provider;

/*
 * $Id: RC4.java,v 1.18 1999/01/18 05:52:02 leachbj Exp $
 * $Author: leachbj $
 *
 * Copyright (C) 1996-1998 Australian Business Access Pty Ltd.
 * All rights reserved.
 * 
 * Use, modification, copying and distribution of this software is subject the
 * terms and conditions of the ABA Public Licence. See the file
 * "PUBLIC_LICENCE" for additional information.
 *
 * If you have not received a copy of the Public Licence, you must destroy all
 * copies of this file immediately. 
 *
 * $Source: /aba/CVSROOT/jdk1.1/src/au.net.aba/crypto/provider/RC4.java,v $
 * $Revision: 1.18 $
 * $Date: 1999/01/18 05:52:02 $
 * $State: Exp $
 */

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;

/**
 * A class that provides RC4 stream encryption.
 */
public class RC4 extends CipherSpi
{
	public final static String ident = "$Id: RC4.java,v 1.18 1999/01/18 05:52:02 leachbj Exp $";

	//==================================
	// Private Implementation
	//==================================

	private static final int CONTEXT_LENGTH = 256;

	/*
	 * The internal state of the RC4 algorithm.
	 */
	private short[] state = null;

	private short x;
	private short y;
	/**
	 * Encrypt the specified byte and return the encrypted byte.
	 *
	 * @param plainText	The plain text data.
	 * @return		The encrypted data.
	 */
	public synchronized byte cipher(
		byte plainText)
	{
		// internal to this method, we use chars to perform
		// the ciphering, since these are unsigned values and
		// therefore not subject to the weirdness of sign extension.
		int xorIndex;
		int _x = x;
		int _y = y;

		_x = (_x + 1) % CONTEXT_LENGTH;
		_y = (state[_x] + _y) % CONTEXT_LENGTH;
		short tmp = state[_x];
		state[_x] = state[_y];
		state[_y] = tmp;
		xorIndex = (state[_x] + state[_y]) % CONTEXT_LENGTH;

		x = (short)_x;
		y = (short)_y;

		return (byte)((plainText ^ state[xorIndex]) & 0xff);
	}
	/**
	 * Encrypts or decrypts data in a single-part operation, or finishes
	 * a multiple-part operation. The data is encrypted or decrypted,
	 * depending on how this cipher was initialised. 
	 *
	 * @param in	the data to be processed.
	 * @param inOff	the offset in the in array that processing should start
	 *	from.
	 * @param inLen	the number of bytes of data to be processed.
	 * @return the resulting data (null if there isn't enough).
	 */
	protected byte[] engineDoFinal(
		byte[]	in,
		int	inOff,
		int	inLen)
	{
		return engineUpdate(in, inOff, inLen);
	}
	/**
	 * Encrypts or decrypts data in a single-part operation, or finishes
	 * a multiple-part operation. 
	 *
	 * @param in		the data to be processed.
	 * @param inOff		the offset in the in array that processing
	 * 	should start from.
	 * @param inLen		the number of bytes of data to be processed.
	 * @param out		the array that the output is to be put into.
	 * @param outOff	the offset in the out array that processed data
	 * 	should start being written at.
	 * @return the number of bytes that were output to the out array.
	 * @exception ShortBufferException	The provided output buffer
	 * 	is too small for the decrypted result.
	 */
	protected int engineDoFinal(
		byte[]	in,
		int	inOff,
		int	inLen,
		byte[]	out,
		int	outOff)
		throws ShortBufferException
	{
		return engineUpdate(in, inOff, inLen, out, outOff);
	}
	/**
	 * Returns the block size (in bytes). 
	 *
	 * @return the block size (in bytes), or 0 if the underlying algorithm
	 * 	is not a block cipher 
	 */
	protected int engineGetBlockSize()
	{
		return 1;
	}
	/**
	 * Returns the initialisation vector for this Cipher - in this case null
	 *
	 * @return null
	 */
	protected byte[] engineGetIV()
	{
		return null;
	}
	/**
	 * Returns the length in bytes that an output buffer would need to be
	 * in order to hold the result of the next update or doFinal operation,
	 * given the input length inputLen (in bytes).
	 *
	 * @param inputLen	the length of bytes we are planning to input.
	 * @return the output size for input bytes plus what is in the buffer.
	 */
	protected int engineGetOutputSize(
		int	inputLen)
	{
		return inputLen;
	}
	/**
	 * Returns the parameters used with this cipher.
	 *
	 * @return the algorithm parameters.
	 */
	protected AlgorithmParameters engineGetParameters()
	{
		return null;
	}
	/**
	 * Initialises this cipher with a key and a source of randomness,
	 * using the AlgorithmParameters construct. 
	 *
	 * @param opMode	the cipher mode.
	 * @param key		the key to be used.
	 * @param params	the algorithm parameters to be used.
	 * @param rand		the random number generator to be used.
	 * @exception InvalidKeyException if the key is of the wrong type.
	 */
	protected void engineInit(
		int			opMode,
		Key			key,
		AlgorithmParameters	params,
		SecureRandom		rand)
		throws InvalidKeyException
	{
		state = new short[CONTEXT_LENGTH];

		if (!((key instanceof RC4Key)
				|| (key instanceof SecretKeySpec)))
		{
			throw new InvalidKeyException("not a RC4 Key");
		}

		prepare(key.getEncoded());
	}
	/**
	 * Initialises this cipher with a key and a source of randomness. 
	 *
	 * @param opMode	the cipher mode.
	 * @param key		the key to be used.
	 * @param rand		the random number generator to be used.
	 * @exception InvalidKeyException if the key is of the wrong type.
	 */
	protected void engineInit(
		int		opMode,
		Key		key,
		SecureRandom	rand)
		throws InvalidKeyException
	{
		engineInit(opMode, key, (AlgorithmParameterSpec)null, rand);
	}
	/**
	 * Initialises this cipher with a key and a source of randomness. 
	 *
	 * @param opMode	the cipher mode.
	 * @param key		the key to be used.
	 * @param params	the parameter spec to be used.
	 * @param rand		the random number generator to be used.
	 * @exception InvalidKeyException if the key is of the wrong type.
	 */
	protected void engineInit(
		int			opMode,
		Key			key,
		AlgorithmParameterSpec	params,
		SecureRandom		rand)
		throws InvalidKeyException
	{
		state = new short[CONTEXT_LENGTH];

		if (!((key instanceof RC4Key)
				|| (key instanceof SecretKeySpec)))
		{
			throw new InvalidKeyException("not a RC4 Key");
		}

		prepare(key.getEncoded());
	}
	/**
	 * Sets the mode of this cipher. Not applicable.
	 *
	 * @param mode	the mode we want.
	 */
	public void engineSetMode(
		String mode)
	throws NoSuchAlgorithmException
	{
		throw new NoSuchAlgorithmException("RC4 does not support " + mode);
	}
	/**
	 * Sets the padding mechanism of this cipher. Not applicable.
	 *
	 * @param padding	the type of padding we want.
	 */
	public void engineSetPadding(
		String padding)
	throws NoSuchPaddingException
	{
		throw new NoSuchPaddingException("RC4 does not support " + padding);
	}
	/**
	 * Continues a multiple-part encryption or decryption operation
	 * (depending on how this cipher was initialised), processing another
	 * data part. Returns null if cipher didn't receive enough data.
	 *
	 * @param in	the data to be processed.
	 * @param inOff	the offset in the in array that processing should start
	 * 	from.
	 * @param inLen	the number of bytes of data to be processed.
	 * @return the resulting data (null if more is required).
	 */
	protected byte[] engineUpdate(
		byte[]	 	in,
		int		inOff,
		int		inLen)
	{
		byte[]		tmp;

		tmp = new byte[inLen];

		for (int i = 0; i < inLen; i++)
		{
			tmp[i] = cipher(in[i + inOff]);
		}

		return tmp;
	}
	/**
	 * Continues a multiple-part encryption or decryption operation
	 * (depending on how this cipher was initialised), processing another
	 * data part.
	 *
	 * @param in		the data to be processed.
	 * @param inOff		the offset in the in array that processing
	 * 	should start from.
	 * @param inLen		the number of bytes of data to be processed.
	 * @param out		the array that the output is to be put into.
	 * @param outOff	the offset in the out array that processed data
	 * 	should start being written at.
	 * @return the number of bytes that were output to the out array.
	 * @exception ShortBufferException  The provided output buffer is
	 * 	too short.
	 */
	protected int engineUpdate(
		byte[]	in,
		int	inOff,
		int	inLen,
		byte[]	out,
		int	outOff)
		throws ShortBufferException
	{
		/*
		 * Make sure output buffer is long enough
		 */
		if ((outOff + inLen) > out.length)
		{
			throw new ShortBufferException(
						"Output buffer too short.");
		}

		for (int i = 0; i < inLen; i++)
		{
			out[i + outOff] = cipher(in[i + inOff]);
		}

		return inLen;
	}
	/*
	 * Initialise the internal state of the RC4 algorithm
	 * from the specified key data.
	 *
	 * @param data		The bytes to initialise the state from.
	 */
	private synchronized void prepare(byte[] data)
	{
		int index1 = 0;
		int index2 = 0;

		x = 0;
		y = 0;

		for (short i = 0; i < state.length; i++)
		{
			state[i] = i;
		}

		for (int i = 0; i < state.length; i++)
		{
			index2 = (((int)data[index1] & 0xff)
				+ state[i] + index2) % CONTEXT_LENGTH;
			short tmp = state[i];
			state[i] = state[index2];
			state[index2] = tmp;
			index1 = (index1 + 1) % data.length;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -