📄 cipher.java
字号:
if (out == null) throw new NullPointerException();// int outStart = outOffset; if (buffer == null) { if (tracing) { traceMethod("engineUpdate(<" + dump(in) + ">, " + inOffset + ", " + inLen + ", <" + dump(out) + ">, " + outOffset + ")"); int result = engineUpdate(in, inOffset, inLen, out, outOffset); traceResult(result); outOffset += result; if (isFinal && implBuffering) { traceMethod("engineCrypt(<" + dump(out) + ">, " + outOffset + ")"); result = engineCrypt(out, outOffset); traceResult(result); outOffset += result; } } else { outOffset += engineUpdate(in, inOffset, inLen, out, outOffset); if (isFinal && implBuffering) outOffset += engineCrypt(out, outOffset); } return outOffset-outStart; } // Avoid overlapping input and output regions. if (in == out) { if ((outOffset >= inOffset && outOffset < (long)inOffset+inLen) || (inOffset >= outOffset && inOffset < (long)outOffset+ outBufferSizeInternal(inLen, isFinal))) { byte[] newin = new byte[inLen]; System.arraycopy(in, inOffset, newin, 0, inLen); in = newin; inOffset = 0; } } if (isFinal) { if (state == ENCRYPT) { // Simulate calling update. After this, the data to be padded will // be in the buffer. outOffset += updateInternal(in, inOffset, inLen, out, outOffset, false); // If no padding scheme is set, there should be no data to pad. if (padding == null) { if (buffered > 0) { buffered = 0; throw new IllegalBlockSizeException(getAlgorithm() + ": Non-padding cipher in ENCRYPT state with an incomplete final block"); } return outOffset-outStart; } // Pad the buffer in-place (there should be enough room). padding.pad(buffer, 0, buffered); buffered = 0; // Encrypt it. if (tracing) traceMethod("engineUpdate(<" + dump(buffer) + ">, 0, " + inputSize + ", <" + dump(out) + ">, " + outOffset + ")"); int result = engineUpdate(buffer, 0, inputSize, out, outOffset); if (tracing) traceResult(result); outOffset += result; return outOffset-outStart; } else if (padding != null) { if (inLen == 0) return 0;// throw new IllegalBlockSizeException(getAlgorithm() +// ": Cipher in DECRYPT state with an incomplete final block"); // Simulate calling update on all but the last byte. outOffset += updateInternal(in, inOffset, inLen-1, out, outOffset, false); // The amount of buffered data should now be inputSize-1. if (buffered != inputSize-1) { buffered = 0; throw new IllegalBlockSizeException(getAlgorithm() + ": Cipher in DECRYPT state with an incomplete final block"); } // Copy the last byte. buffer[buffered] = in[inOffset+inLen-1]; buffered = 0; // Decrypt the buffer. byte[] temp = new byte[outBufferSizeInternal(inputSize, false)]; if (tracing) traceMethod("engineUpdate(<" + dump(buffer) + ">, 0, " + inputSize + ", <" + dump(temp) + ">, 0)"); int result = engineUpdate(buffer, 0, inputSize, temp, 0); if (tracing) traceResult(result); // Unpad the resulting block, and copy it to the output array. int len = padding.unpad(temp, 0, temp.length); System.arraycopy(temp, 0, out, outOffset, len); outOffset += len; return outOffset-outStart; } /* state == DECRYPT && padding == null: fall through */ } if (buffered > 0) { // There is data currently buffered. Test whether the buffered // data and the supplied data together make up at least one // block. if ((long)inLen+buffered < inputSize) { // no, so nothing to crypt System.arraycopy(in, inOffset, buffer, buffered, inLen); buffered += inLen; return 0; } // Complete the buffered block and crypt it. int remainder = inputSize-buffered; System.arraycopy(in, inOffset, buffer, buffered, remainder); inOffset += remainder; inLen -= remainder; if (tracing) traceMethod("engineUpdate(<" + dump(buffer) + ">, 0, " + inputSize + ", <" + dump(out) + ">, " + outOffset + ")"); int result = engineUpdate(buffer, 0, inputSize, out, outOffset); if (tracing) traceResult(result); outOffset += result; } // Buffer anything after the last supplied complete block. buffered = inLen % inputSize; if (buffered > 0) { System.arraycopy(in, inOffset+inLen-buffered, buffer, 0, buffered); inLen -= buffered; } // inLen is now a multiple of inputSize. while (inLen > 0) { if (tracing) traceMethod("engineUpdate(<" + dump(in) + ">, " + inOffset + ", " + inputSize + ", <" + dump(out) + ">, " + outOffset + ")"); int result = engineUpdate(in, inOffset, inputSize, out, outOffset); if (tracing) traceResult(result); outOffset += result; inOffset += inputSize; inLen -= inputSize; } return outOffset-outStart;} catch (RuntimeException e) { if (tracing) e.printStackTrace(); exception = true; throw e;} finally { if (DEBUG && debuglevel >= 5 && tracing && !exception) traceResult(outOffset-outStart);} } /** * Sets the specified algorithm parameter to the specified value. * <p> * This method supplies a general-purpose mechanism through which it is * possible to set the various parameters of this object. A parameter may * be any settable parameter for the algorithm, such as block size, * a source of random bits for IV generation (if appropriate), or an * indication of whether or not to perform a specific but optional * computation. A uniform algorithm-specific naming scheme for each * parameter is desirable but left unspecified at this time. * <p> * <strong><a href="../guide/ijce/JCEDifferences.html">This method * is not supported in JavaSoft's version of JCE.</a></strong> * * @param param the string identifier of the parameter. * @param value the parameter value. * @exception NullPointerException if param == null * @exception NoSuchParameterException if there is no parameter with name * param for this cipher implementation. * @exception InvalidParameterException if the parameter exists but cannot * be set (for example because the cipher is in the * wrong state). * @exception InvalidParameterTypeException if value is the wrong type * for this parameter. */ public void setParameter(String param, Object value) throws NoSuchParameterException, InvalidParameterException, InvalidParameterTypeException { if (param == null) throw new NullPointerException("param == null"); if (tracing) traceVoidMethod("engineSetParameter(\"" + param + "\", <" + value + ">)"); engineSetParameter(param, value); } /** * Gets the value of the specified algorithm parameter. * <p> * This method supplies a general-purpose mechanism through which it * is possible to get the various parameters of this object. A parameter * may be any settable parameter for the algorithm, such as block size, * a source of random bits for IV generation (if appropriate), or an * indication of whether or not to perform a specific but optional * computation. A uniform algorithm-specific naming scheme for each * parameter is desirable but left unspecified at this time. * <p> * <strong><a href="../guide/ijce/JCEDifferences.html">This method * is not supported in JavaSoft's version of JCE.</a></strong> * * @param param the string name of the parameter. * @return the object that represents the parameter value. * @exception NullPointerException if param == null * @exception NoSuchParameterException if there is no parameter with name * param for this cipher implementation. * @exception InvalidParameterException if the parameter exists but cannot * be read. */ public Object getParameter(String param) throws NoSuchParameterException, InvalidParameterException { if (param == null) throw new NullPointerException("param == null"); if (tracing) traceMethod("engineGetParameter(\"" + param + "\")"); Object result = engineGetParameter(param); if (tracing) traceResult("<" + result + ">"); return result; } /** * Returns a clone of this cipher. * <p> * Note: In JavaSoft's version of JCE, <code>Cipher.clone()</code> is * protected. This is not very useful, since then an application (as opposed * to the cipher implementation itself) is not able to call it. * * @exception CloneNotSupportedException if the cipher is not cloneable. */ public Object clone() throws CloneNotSupportedException { if (this instanceof Cloneable) { return super.clone(); } else { throw new CloneNotSupportedException(); } } public String toString() { return "Cipher [" + getProvider() + " " + getAlgorithm() + "/" + getMode() + "/" + getPadding() + "]"; }// SPI methods//............................................................................ /** * <b>SPI</b>: Sets the object that will implement padding for this cipher. * <p> * Cipher implementations may override this method in order to be notified * when the padding scheme is set (in this case they should always call * <code>super.engineSetPaddingScheme(padding)</code>). Normally, overriding * this method is not required. * * @exception IllegalStateException if the cipher is already initialized. */ protected void engineSetPaddingScheme(PaddingScheme padding) { if (state != UNINITIALIZED) throw new IllegalStateException("Cipher is already initialized"); this.padding = padding; } /** * <b>SPI</b>: Returns the length of a block, in bytes. Ciphers for * which plaintext and ciphertext blocks are the same size may override * this method. Otherwise, both enginePlaintextBlockSize and * engineCiphertextBlockSize should be overridden. * <p> * The value may change when <code>initEncrypt</code> or * <code>initDecrypt</code> is called, but it should not change at * other times. * * @return the length in bytes of a block for this cipher. */ protected int engineBlockSize() { throw new Error( "cipher classes must implement either engineBlockSize, or " + "enginePlaintextBlockSize and engineCiphertextBlockSize"); } /** * <b>SPI</b>: Returns the length of a plaintext block, in bytes. * For byte-oriented stream ciphers, this method should return 1. * <p> * The value may change when <code>initEncrypt</code> or * <code>initDecrypt</code> is called, but it should not change at * other times. * <p> * The default implementation returns <code>engineBlockSize()</code>. * * @return the length in bytes of a plaintext block for this cipher. */ protected int enginePlaintextBlockSize() { return engineBlockSize(); } /** * <b>SPI</b>: Returns the length of a ciphertext block, in bytes. * For byte-oriented stream ciphers, this method should return 1. * <p> * The value may change when <code>initEncrypt</code> or * <code>initDecrypt</code> is called, but it should not change at * other times. * <p> * The default implementation returns <code>engineBlockSize()</code>. * * @return the length in bytes of a ciphertext block for this cipher. */ protected int engineCiphertextBlockSize() { return engineBlockSize(); } /** * <b>SPI</b>: Returns the length of output buffer required for a given * length of input, in bytes. <code>isFinal</code> is true when this * is the final block of input. * <p> * If <code>implBuffering</code> is false, the <code>inLen</code> * parameter already takes into account the length of any required * padding, and buffered data. In this case <code>inLen</code> will be * a multiple of the input block size (this may only be tru
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -