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

📄 blockcipher.java

📁 面向应用的智能安全代理平台和工具包是一个综合网络应用的安全共性需求而设计和实现的一个通用性的网络信息安全应用支撑平台
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * 	for initialising this cipher 
	 * @exception InvalidAlgorithmParameterException if the given algorithm
	 * 	parameters are inappropriate for this cipher, or if this
	 * 	cipher is being initialised fro decryption and requires
	 * 	algorithm parameters and params is null
	 */
	protected void engineInit(
		int opmode,
		Key key,
		AlgorithmParameterSpec params,
		SecureRandom random)
	throws InvalidKeyException, InvalidAlgorithmParameterException
	{
		reset();

		this.mode = opmode;
		this.random = random;
		this.key = key;

		if (streamMode == CBC)
		{
			int blockSize = engineGetBlockSize();

			/*
			 * create two buffers, one for the original
			 * iv, the other for the "current" iv
			 */
			ivec = new byte[blockSize];
			cbcV = new byte[blockSize];

			if (params instanceof IvParameterSpec)
			{
				/*
				 * copy the supplied iv
				 */
				System.arraycopy(
					((IvParameterSpec)params).getIV(),
					0, ivec, 0, blockSize);
			}
			else
			{
				/*
				 * create a random one, it will be
				 * added to the output stream
				 */
				if (params instanceof InlineIvParameterSpec)
				{
					ivInline = true;
					firstBlock = true;
					ivEncrypted = ((InlineIvParameterSpec)params).isEncryptedIv();
				}

				random.nextBytes(ivec);
			}

			/*
			 * copy the iv for use
			 */
			System.arraycopy(ivec, 0, cbcV, 0, blockSize);
		}

		setKey(key);
	}
	/**
	 * Sets the mode of this cipher.  Valid modes for are;
	 * ECB or CBC.
	 *
	 * @param mode the cipher mode 
	 * @exception NoSuchAlgorithmException	if the requested cipher mode
	 * 	does not exist 
	 */
	protected void engineSetMode(String mode)
	throws NoSuchAlgorithmException
	{
/*
		System.out.println("engineSetMode("+mode+")");
*/
		if (mode.equals("ECB"))
		{
			streamMode = ECB;
		}
		else if (mode.equals("CBC"))
		{
			streamMode = CBC;
		}
		else
		{
			throw new NoSuchAlgorithmException(
				"Mode " + mode + " not supported.");
		}
	}
	/**
	 * Sets the padding mechanism of this cipher.  Valid padding mechanisms
	 * are; "PKCS5Padding" and "NoPadding".
	 *
	 * @param padding the padding mechanism
	 * @exception NoSuchPaddingException if the requested padding 
	 * 	mechanism does not exist.
	 */
	protected void engineSetPadding(String padding)
	throws NoSuchPaddingException
	{
/*
		System.out.println("engineSetPadding("+padding+")");
*/
		if (padding.equals("PKCS5Padding"))
		{
			paddedStream = true;
		}
		else if (padding.equals("NoPadding"))
		{
			paddedStream = false;
		}
		else
		{
			throw new NoSuchPaddingException(
				"Unsupported padding " + padding);
		}
	}
	/**
	 * Continues a multiple-part encryption or decryption operation
	 * (depending on how this cipher was initialised), processing another
	 * data part. 
	 * <p>
	 * The first inputLen bytes in the input buffer, starting at
	 * inputOffset, are processed, and the result is stored in a new buffer.
	 *
	 * @param input the input buffer 
	 * @param inputOffset the offset in input where the input starts 
	 * @param inputLen the input length 
	 * @return the new buffer with the result, or null if the underlying
	 *    cipher is a block cipher and the input data is too short to
	 *    result in a new block. 
	 */
	protected byte[] engineUpdate(
		byte[] input,
		int inputOff,
		int inputLen)
	{
		byte[] output = null;
		int len = engineGetOutputSize(inputLen);
		if (len != 0)
		{
			output = new byte[len];
		}

/*
		System.out.println("len = " + len);
*/

		try
		{
			len = engineUpdate(input, inputOff, inputLen,
				output, 0);
		}
		catch (ShortBufferException e)
		{
			// this shouldnt happen
			e.printStackTrace();
			throw new RuntimeException("ShortBufferException: "
				+ e.getMessage());
		}

/*
		System.out.println("len = " + len);
*/

		/*
		 * our initial buffer was too big!
		 */
		if (output != null && len != output.length)
		{
/*
			System.out.println("len = " + len + " output.length = " + output.length);
*/
			byte[] buf = new byte[len];
			System.arraycopy(output, 0, buf, 0, len);

			output = buf;
		}


		return output;
	}
	/**
	 * Continues a multiple-part encryption or decryption operation
	 * (depending on how this cipher was initialised), processing another
	 * data part. 
	 * <p>
	 * The first inputLen bytes in the input buffer, starting at
	 * inputOffset, are processed, and the result is stored in the output
	 * buffer, starting at outputOffset. 
	 * <p>
	 * If the output buffer is too small to hold the result, a
	 * ShortBufferException is thrown. In this case, repeat this call with
	 * a larger output buffer. Use getOutputSize to determine how big the
	 * output buffer should be. 
	 * 
	 * @param input the input buffer 
	 * @param inputOffset the offset in input where the input starts 
	 * @param inputLen the input length 
	 * @param output the buffer for the result 
	 * @param outputOffset the offset in output where the result is stored 
	 * 
	 * @exception ShortBufferException if the given output buffer is too
	 *     small to hold the result 
	 *
	 * @return the number of bytes stored in output 
	 */
	protected int engineUpdate(
		byte[] input,
		int inputOff,
		int inputLen,
		byte[] output,
		int outputOff)
	throws ShortBufferException
	{
		try
		{
			return processAllBlocks(input, inputOff, inputLen,
				output, outputOff);
		}
		catch (BadPaddingException bpe)
		{
			// this shouldnt happen
			bpe.printStackTrace();
		}
		catch (IllegalBlockSizeException ibse)
		{
			// this shouldnt happen
			ibse.printStackTrace();
		}

		throw new ShortBufferException(
			"Internal error, see stacktrace on console.");
	}
	/**
	 * This method is used to process in block sized chunks all the
	 * input data.
	 */
	private int processAllBlocks(
		byte[] input,
		int inputOff,
		int inputLen,
		byte[] output,
		int outputOff)
	throws BadPaddingException, IllegalBlockSizeException
	{
		int blockSize = engineGetBlockSize();
		int resultBytes = 0;

/*
		System.out.println (
			"processAllBlocks: input " + input
			+ " inputOff " + inputOff
			+ " inputLen " + inputLen
			+ " output " + output
			+ " outputOff " + outputOff
			+ " bufferPos " + bufferPos);
*/

		if (inputLen < (blockSize - bufferPos))
		{
			if (inputLen > 0)
			{
				System.arraycopy(input, inputOff, buffer,
					bufferPos, inputLen);
				bufferPos += inputLen;
			}
			return 0;
		}
		else if (inputLen == (blockSize - bufferPos))
		{
			if (inputLen > 0)
			{
				System.arraycopy(input, inputOff, buffer,
					bufferPos, inputLen);
			}

			if (paddedStream)
			{
				bufferPos += inputLen;
				return 0;
			}
			else
			{
				resultBytes = processBlock(buffer, 0,
					blockSize, output, outputOff);
				bufferPos = 0;
				return resultBytes;
			}
		}
		else
		{
			int n = blockSize - bufferPos;
			System.arraycopy(input, inputOff, buffer, bufferPos, n);
			resultBytes = processBlock(buffer, 0, blockSize,
				output, outputOff);

			inputLen -= n;
			inputOff += n;
			outputOff += resultBytes;
			bufferPos = 0;
		}

		int blockCount = (inputLen + blockSize - 1) / blockSize;
		int lastBlockSize = inputLen % blockSize;

		/*
		 * decode each element of the array, chopping the array
		 * into blocks to match the current key.
		 */
		for (int i = 0; i < blockCount - 1; i++)
		{
			int n = processBlock(input, inputOff, blockSize,
				output, outputOff);

			inputOff += blockSize;
			outputOff += n;
			resultBytes += n;
		}

		if (lastBlockSize == 0)    /* exact multiple */
		{
			/*
			 * if we are padded we need to hold the last
			 * block unless we are an RSA cipher.
			 */
			if (paddedStream)
			{
				System.arraycopy(input, inputOff,
					buffer, 0, blockSize);
				bufferPos = blockSize;
			}
			else
			{
				int n = processBlock(input, inputOff,
					blockSize, output, outputOff);
				outputOff += n;
				resultBytes += n;
				bufferPos = 0;
			}
		}
		else
		{
			System.arraycopy(input, inputOff,
				buffer, 0, lastBlockSize);
			bufferPos = lastBlockSize;
		}

		return resultBytes;
	}
	/**
	 * This method is used to process complete blocks.  The cipher
	 * dependent encrypt or decrypt function will be called depending
	 * on how this cipher is currently initialised.
	 */
	private int processBlock(
		byte[] input,
		int inputOff,
		int len,
		byte[] output,
		int outputOff)
	throws BadPaddingException, IllegalBlockSizeException
	{
		int blockSize = engineGetBlockSize();
		int resultLen = 0;

/*
		System.out.println (
			"processBlock: input " + input
			+ " input.length " + input.length
			+ " inputOff " + inputOff
			+ " len " + len
			+ " output " + output
			+ " output.length " + output.length
			+ " outputOff " + outputOff);
*/

		/*
		 * if we are doing the first block and have an inline IV
		 * copy/encrypt the IV to the output or copy/decrypt the
		 * IV from the input
		 */
		if (firstBlock && ivInline)
		{
			firstBlock = false;
			if (mode == Cipher.ENCRYPT_MODE)
			{
				int n;
				if (ivEncrypted)
				{
					/*
					 * encrypt the ivec to the output
					 */
					n = encryptBlock(ivec, 0, blockSize,
						output, outputOff);
				}
				else
				{
					/*
					 * copy the ivec to the output
					 */
					System.arraycopy(ivec, 0, output,
						outputOff, blockSize);
					n = blockSize;
				}

				/*
				 * just produced a block of output
				 */
				outputOff += n;
				resultLen += n;
			}
			else // Cipher.DECRYPT_MODE
			{
				if (ivEncrypted)
				{
					/*
					 * decrypt input to the ivec
					 */
					decryptBlock(input, inputOff, len,
						ivec, 0);
				}
				else
				{
					/*
					 * copy input to ivec
					 */
					System.arraycopy(input, inputOff,
						ivec, 0, blockSize);
				}


				/*
				 * copy recovered ivec to cbcV
				 */
				System.arraycopy(ivec, 0, cbcV, 0, blockSize);

				/*
				 * we have consumed a block of input so we return,
				 * however there is no output
				 */
				return 0;
			}
		}

		/*
		 * process the next block
		 */
		if (mode == Cipher.ENCRYPT_MODE)
		{
			if (streamMode == CBC)
			{
				/*
				 * XOR the cbcV and the input,
				 * then encrypt the cbcV
				 */
				for (int i = 0; i < blockSize; i++)
				{
					cbcV[i] ^= input[inputOff + i];
				}

				input = cbcV;
				inputOff = 0;
			}

			resultLen += encryptBlock(input, inputOff, len,
				output, outputOff);

			if (streamMode == CBC)
			{
				/*
				 * copy ciphertext to cbcV
				 */
				System.arraycopy(output, outputOff, cbcV, 0,
					blockSize);
			}
		}
		else
		{
			resultLen += decryptBlock(input, inputOff, len,
				output, outputOff);

			if (streamMode == CBC)
			{
				/*
				 * XOR the cbcV and the output
				 */
				for (int i = 0; i < blockSize; i++)
				{
					output[outputOff + i] ^= cbcV[i];
				}

				/*
				 * copy ciphertext to cbcV
				 */
				System.arraycopy(input, inputOff, cbcV, 0,
					blockSize);
			}
		}

		return resultLen;
	}
	/**
	 * Reset the Cipher to uninitialised.
	 */
	protected void reset()
	{
		/*
		 * zero out our internal buffer
		 */
		if (buffer != null)
		{
			for (int i = 0; i < buffer.length; i++)
			{
				buffer[0] = 0;
			}
			buffer = null;
		}

		/*
		 * reset the cbcV
		 */
		if (ivec != null)
		{
			System.arraycopy(ivec, 0, cbcV, 0, engineGetBlockSize());
		}

		/*
		 * rekey the cipher
		 */
		if (key != null)
		{
			try
			{
				setKey(key);
			}
			catch (InvalidKeyException e)
			{
				// ignore it
			}
		}

		buffer = new byte[engineGetBlockSize()];
		bufferPos = 0;
		firstBlock = ivInline;
	}
	/**
	 * Re-key the cipher.  If the provided Key is not compatible
	 * with this cipher the exception should throw an InvalidKeyException.
	 */
	protected abstract void setKey(Key key) throws InvalidKeyException;
}

⌨️ 快捷键说明

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