📄 cipherinputstream.java
字号:
// $Id: CipherInputStream.java,v 1.1.1.1 2002/08/27 11:49:30 grosbois Exp $//// $Log: CipherInputStream.java,v $// Revision 1.1.1.1 2002/08/27 11:49:30 grosbois// Imported source from cryptix 3.2//// Revision 1.10 2000/08/17 11:35:24 edwin// Package move java.* -> xjava.*, which is needed for JDK 1.3 compatibility.// I had to break permission support even further to make this work (I don't// believe it was working in the first place, so it's not really a problem).//// Revision 1.9 1997/12/03 03:36:06 hopwood// + Committed changes below.//// Revision 1.7.1 1997/12/02 hopwood// + If the return value from read([B,I,I) would be 0 on the last read before// EOF, force it to -1.// + outBuf was missing an index pointer, so if more than one consecutive// read was from outBuf, all but the first would return junk.// + Added close() method, to be consistent with CipherOutputStream.//// Revision 1.7 1997/12/02 03:19:50 hopwood// + Committed changes below.//// Revision 1.6.1 1997/12/02 hopwood// + Previously buffered data was not being taken into account in the return// value of read([B,I,I).// + The loop in readFully would sometimes not terminate.// + Added tempBuf to hold the single byte in read(). Neither of the// preallocated arrays should be used for this, as they will be overwritten.// + Changed read() to correctly handle a return value of 0 from read([B,I,I).//// Revision 1.6 1997/12/01 05:20:27 raif// + Added test for cipher==null in available(). That method// is called by Reader subclasses even when the cipher object// is no more.//// Revision 1.5 1997/12/01 03:37:28 hopwood// + Committed changes below.//// Revision 1.4.1 1997/11/30 hopwood// + The previous implementation was broken because the cipher might output more// bytes than were requested as input from the stream. An extra buffer, outBuf,// is needed to fix this.// + A single read from the underlying stream might not be sufficient; now we// repeat until the correct number of bytes is read.// + "if (length < out.length - offset)" should be "if (length > out.length - offset)".// + More debugging calls added.//// Revision 1.4 1997/11/29 04:45:12 hopwood// + Committed changes below.//// Revision 1.3.1 1997/11/18 David Hopwood// + Changed behaviour of read(I,I,I) for short output arrays back to// Raif's 1.2 revision.//// Revision 1.3 1997/11/21 04:31:18 hopwood// + Committed changes below.//// Revision 1.2.2 1997/11/20 David Hopwood// + Made skip and available synchronized.//// Revision 1.2.1 1997/11/18 David Hopwood// + Reversed the change made in 1.2. If the client passes an array that// is not long enough for the requested number of bytes, it's a bug// in the client code, not an end-of-stream condition.//// Revision 1.2 1997/11/07 05:53:27 raif// + Crippled the ArrayIndexOutOfBoundsException in read() since// semantically a return of -1 should/would indicate this.//// Revision 1.1.1.1 1997/11/03 22:36:57 hopwood// + Imported to CVS (tagged as 'start').//// Revision 0.1.0.2 1997/11/01 David Hopwood// + Implemented skip, available, and markSupported methods.// + Changed the buffering behaviour to distinguish padding block ciphers// in DECRYPT mode from other ciphers. This is to ensure that the minimum// amount is always buffered.// + Updated documentation.//// Revision 0.1.0.1 1997/07/20 R. Naffah// + Tests OK.// + Fixed the read() methods.//// Revision 0.1.0.0 1997/??/?? David Hopwood// + Original version.//// $Endlog$/* * Copyright (c) 1997 Systemics Ltd * on behalf of the Cryptix Development Team. All rights reserved. */package xjava.security;import java.io.*;/** * A FilterInputStream that encrypts or decrypts the data passing through * it. Typically, this stream would be used as a filter to read * an encrypted file. It can also be used to encrypt network communications * (although this would normally require use of a stream cipher, or a block * cipher in a stream-like mode such as CFB or OFB). * <p> * This class has a constructor that takes an input stream and a Cipher * as arguments. The cipher is used to encrypt or decrypt all data read * through the stream. * <p> * The data is encrypted or decrypted, depending on the initialisation * state of the Cipher. To get the encryption/decryption result bytes, * make one or more calls to the <code>read</code> methods. One * <code><a href="#read()">read</a></code> method, with no arguments, * returns the next result byte. The other * <code><a href="#read(byte[], int, int)">read</a></code> method returns * multiple result bytes at once. * <p> * For block ciphers, some buffering of the data received from the input * stream is done. The buffer length is calculated as follows: * <pre> * buffer length = cipher.getInputBlockSize() + * (cipher.isPaddingBlockCipher() && * cipher.getState() == Cipher.DECRYPT) ? 1 : 0 * </pre> * Each read operation will attempt to completely fill the buffer. The maximum * number of bytes that can remain unprocessed after each <code>read</code> call * is one less than the buffer length. In the case of a padding block cipher in * DECRYPT mode, this means that one full ciphertext block may remain * unprocessed, because it is necessary to read an extra byte in order to * determine whether this is the last block of the stream. (It would be * incorrect to process a block without making this check, since it may have * padding bytes that need to be stripped out.) * <p> * When EOF is reached for a padding/unpadding cipher in DECRYPT mode, the * the decryption result is unpadded. If EOF is encountered part-way through * a block, an <samp>IllegalBlockSizeException</samp> is thrown. * <p> * When EOF is reached for a padding/unpadding cipher in ENCRYPT mode, the * last block is padded before encryption. If the cipher does not support * padding and the last block is incomplete, an <samp>IllegalBlockSizeException</samp> * is thrown. * <p> * For stream ciphers, that is, ciphers capable of encrypting or decrypting * a byte at a time, no buffering is necessary. * <p> * Note: calling methods of a cipher while it is being used by a * CipherInputStream (apart from methods that have no side-effects, * like <code>getAlgorithm()</code>, <code>get*BlockSize()</code>, etc.) * will probably result in incorrect or unexpected output. * <p> * <b>Copyright</b> © 1997 * <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the * <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>. * <br>All rights reserved. * <p> * <b>$Revision: 1.1.1.1 $</b> * @author David Hopwood * @author Raif S. Naffah * @since IJCE 1.0.0 * * @see java.security.Cipher * @see java.security.Cipher#getInputBlockSize * @see java.security.Cipher#getOutputBlockSize * @see java.security.CipherOutputStream */public class CipherInputStreamextends FilterInputStream{// Debugging methods and vars.//........................................................................... private static final boolean DEBUG = true; private static int debuglevel = DEBUG ? IJCE.getDebugLevel("CipherInputStream") : 0; private static PrintWriter err = DEBUG ? IJCE.getDebugOutput() : null; private static void debug(String s) { err.println("CipherInputStream: " + s); } private static String dump(byte[] b) { if (b == null) return "null";// if (b.length <= 32) return cryptix.util.core.Hex.toString(b); return b.toString(); }// Variables//........................................................................... private Cipher cipher; private final byte[] preallocated1 = new byte[256]; private final byte[] preallocated2 = new byte[256]; private final byte[] tempByte = new byte[1]; private byte[] outBuf; private int outPtr; private int buffered; private boolean isDPBC; // is a decrypting padding block cipher// Constructor//........................................................................... /** * Constructs an input stream using a cipher that must be * initialised for either encryption or decryption, that is, a * cipher whose state is either <code>ENCRYPT</code> or * <code>DECRYPT</code>. * * @param in the input stream. * @param cipher an initialised cipher. * @exception NullPointerException if is == null || cipher == null * @exception IllegalStateException if cipher.getState() == UNINITIALIZED * * @see java.security.Cipher */ public CipherInputStream(InputStream is, Cipher cipher) { super(is); if (cipher == null) throw new NullPointerException("cipher"); int state = cipher.getState(); if (state != Cipher.ENCRYPT && state != Cipher.DECRYPT) throw new IllegalStateException("cipher is uninitialized"); outBuf = new byte[cipher.getOutputBlockSize()]; // this is an estimate of the required length of outBuf; doesn't // matter if it is incorrect. outPtr = buffered = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -