rc4.java
来自「jpeg2000编解码」· Java 代码 · 共 456 行 · 第 1/2 页
JAVA
456 行
//............................................................................ /** * Will hold the contents of the current set S-box. */ private int[] sBox = new int[256]; /** * The two indices for the S-box computation referred to as i and j * in Schneier. */ private int x, y; /** * The block size of this cipher. Being a stream cipher this value * is 1! */ private static final int BLOCK_SIZE = 1;// Constructor, finalizer, and clone()//............................................................................ /** * Constructs an RC4 cipher object, in the UNINITIALIZED state. * This calls the Cipher constructor with <i>implBuffering</i> false, * <i>implPadding</i> false and the provider set to "Cryptix". */ public RC4() { super(false, false, "Cryptix"); } /** * Cleans up resources used by this instance, if necessary. */ protected final void finalize() { if (native_lock != null) { synchronized(native_lock) { String error = native_finalize(); // may be called more than once if (error != null) debug(error + " in native_finalize"); } } } /** * Always throws a CloneNotSupportedException (cloning of ciphers is not * supported for security reasons). */ public final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); }// Implementation of JCE methods//............................................................................ /** * <b>SPI</b>: Returns the length of an input block, in bytes. * * @return the length in bytes of an input block for this cipher. */ public int engineBlockSize () { return BLOCK_SIZE; } /** * <b>SPI</b>: Initializes this cipher for encryption, using the * specified key. * * @param key the key to use for encryption. * @exception InvalidKeyException if the key is invalid. */ public void engineInitEncrypt(Key key) throws InvalidKeyException { makeKey(key); } /** * <b>SPI</b>: Initializes this cipher for decryption, using the * specified key. * * @param key the key to use for decryption. * @exception InvalidKeyException if the key is invalid. */ public void engineInitDecrypt(Key key) throws InvalidKeyException { makeKey(key); } /** * <b>SPI</b>: This is the main engine method for updating data. * <p> * <i>in</i> and <i>out</i> may be the same array, and the input and output * regions may overlap. * * @param in the input data. * @param inOffset the offset into in specifying where the data starts. * @param inLen the length of the subarray. * @param out the output array. * @param outOffset the offset indicating where to start writing into * the out array. * @return the number of bytes written. * @exception CryptixException if the native library is being used, and it * reports an error. */ protected int engineUpdate(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) { if (inLen < 0) throw new IllegalArgumentException("inLen < 0"); boolean doEncrypt = (getState() == ENCRYPT); // Avoid overlapping input and output regions. if (in == out && (outOffset >= inOffset && outOffset < (long)inOffset+inLen || inOffset >= outOffset && inOffset < (long)outOffset+inLen)) { byte[] newin = new byte[inLen]; System.arraycopy(in, inOffset, newin, 0, inLen); in = newin; inOffset = 0; } if (native_lock != null) { synchronized(native_lock) { // If in == null || out == 0, evaluating their lengths will throw a // NullPointerException. if (inOffset < 0 || (long)inOffset + inLen > in.length || outOffset < 0 || (long)outOffset + inLen > out.length) throw new ArrayIndexOutOfBoundsException(getAlgorithm() + ": Arguments to native_crypt would cause a buffer overflow"); if (0 == native_crypt(native_cookie, in, inOffset, inLen, out, outOffset)) throw new CryptixException(getAlgorithm() + ": Error in native code"); } } else rc4(in, inOffset, inLen, out, outOffset); return inLen; }// Own methods//............................................................................ /** * RC4 encryption/decryption. The input and output regions are assumed not to * overlap. * * @param in the input data. * @param inOffset the offset into in specifying where the data starts. * @param inLen the length of the subarray. * @param out the output array. * @param outOffset the offset indicating where to start writing into * the out array. */ private void rc4(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) { int xorIndex, t; for (int i = 0; i < inLen; i++) { x = (x + 1) & 0xFF; y = (sBox[x] + y) & 0xFF; t = sBox[x]; sBox[x] = sBox[y]; sBox[y] = t; xorIndex = (sBox[x] + sBox[y]) & 0xFF; out[outOffset++] = (byte)(in[inOffset++] ^ sBox[xorIndex]); } } /** * Expands a user-key to a working key schedule. * <p> * The key bytes are first extracted from the user-key and then * used to build the contents of this key schedule. * <p> * The method's only exceptions are when the user-key's contents * are null, or a byte array of zero length. * * @param key the user-key object to use. * @exception InvalidKeyException if one of the following occurs: <ul> * <li> key.getEncoded() == null; * <li> The encoded byte array form of the key is zero-length; * </ul> */ private void makeKey(Key key) throws InvalidKeyException { byte[] userkey = key.getEncoded(); if (userkey == null) throw new InvalidKeyException(getAlgorithm() + ": Null user key"); int len = userkey.length; if (len == 0) throw new InvalidKeyException(getAlgorithm() + ": Invalid user key length"); // If native library available then use it. If not or if // native method returned error then revert to 100% Java. if (native_lock != null) { synchronized(native_lock) { try { linkStatus.check(native_ks(native_cookie, userkey)); return; } catch (Error error) { native_finalize(); native_lock = null;if (DEBUG && debuglevel > 0) debug(error + ". Will use 100% Java."); } } } x = y = 0; for (int i = 0; i < 256; i++) sBox[i] = i; int i1 = 0, i2 = 0, t; for (int i = 0; i < 256; i++) { i2 = ((userkey[i1] & 0xFF) + sBox[i] + i2) & 0xFF; t = sBox[i]; sBox[i] = sBox[i2]; sBox[i2] = t; i1 = (i1 + 1) % len; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?