* @param outputOffset the offset in <code>output</code> where the result * is stored * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] output, int outputOffset) throws IllegalBlockSizeException, ShortBufferException, BadPaddingException { checkCipherState(); // Input sanity check if ((output == null) || (outputOffset < 0)) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(null, 0, 0, output, outputOffset); } /** * 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 initialized. * * <p>The bytes in the <code>input</code> buffer, and any input bytes that * may have been buffered during a previous <code>update</code> operation, * are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in a new buffer. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * @param input the input buffer * * @return the new buffer with the result * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null) { throw new IllegalArgumentException("Null input buffer"); } chooseFirstProvider(); return spi.engineDoFinal(input, 0, input.length); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous <code>update</code> * operation, are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in a new buffer. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * * @return the new buffer with the result * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous <code>update</code> * operation, are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the <code>output</code> buffer. * * <p>If the <code>output</code> buffer is too small to hold the result, * a <code>ShortBufferException</code> is thrown. In this case, repeat this * call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * @param output the buffer for the result * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen, output, 0); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous * <code>update</code> operation, are processed, with padding * (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the <code>output</code> buffer, starting at * <code>outputOffset</code> inclusive. * * <p>If the <code>output</code> buffer is too small to hold the result, * a <code>ShortBufferException</code> is thrown. In this case, repeat this * call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in <code>output</code> where the result * is stored * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0 || outputOffset < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen, output, outputOffset); } /** * 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 initialized. * * <p>All <code>input.remaining()</code> bytes starting at * <code>input.position()</code> are processed. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the output buffer. * Upon return, the input buffer's position will be equal * to its limit; its limit will not have changed. The output buffer's * position will have advanced by n, where n is the value returned * by this method; the output buffer's limit will not have changed. * * <p>If <code>output.remaining()</code> bytes are insufficient to * hold the result, a <code>ShortBufferException</code> is thrown. * In this case, repeat this call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input ByteBuffer * @param output the output ByteBuffer * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalArgumentException if input and output are the * same object * @exception ReadOnlyBufferException if the output buffer is read-only * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if there is insufficient space in the * output buffer * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value * * @since 1.5 */ public final int doFinal(ByteBuffer input, ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); if ((input == null) || (output == null)) { throw new IllegalArgumentException("Buffers must not be null"); } if (input == output) { throw new IllegalArgumentException("Input and output buffers must " + "not be the same object, consider using buffer.duplicate()"); } if (output.isReadOnly()) { throw new ReadOnlyBufferException(); } chooseFirstProvider(); return spi.engineDoFinal(input, output); } /** * Wrap a key. * * @param key the key to be wrapped. * * @return the wrapped key. * * @exception IllegalStateException if this cipher is in a wrong * state (e.g., has not been initialized). * * @exception IllegalBlockSizeException if this cipher is a block * cipher, no padding has been requested, and the length of the * encoding of the key to be wrapped is not a * multiple of the block size. * * @exception InvalidKeyException if it is impossible or unsafe to * wrap the key with this cipher (e.g., a hardware protected key is * being passed to a software-only cipher). */ public final byte[] wrap(Key key) throws IllegalBlockSizeException, InvalidKeyException { if (!(this instanceof NullCipher)) { if (!initialized) { throw new IllegalStateException("Cipher not initialized"); } if (opmode != Cipher.WRAP_MODE) { throw new IllegalStateException("Cipher not initialized " + "for wrapping keys"); } } chooseFirstProvider(); return spi.engineWrap(key); } /** * Unwrap a previously wrapped key. * * @param wrappedKey the key to be unwrapped. * * @param wrappedKeyAlgorithm the algorithm associated with the wrapped * key. * * @param wrappedKeyType the type of the wrapped key. This must be one of * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or * <code>PUBLIC_KEY</code>. * * @return the unwrapped key. * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized). * * @exception NoSuchAlgorithmException if no installed providers * can create keys of type <code>wrappedKeyType</code> for the * <code>wrappedKeyAlgorithm</code>. * * @exception InvalidKeyException if <code>wrappedKey</code> does not * represent a wrapped key of type <code>wrappedKeyType</code> for * the <code>wrappedKeyAlgorithm</code>. */ public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { if (!(this instanceof NullCipher)) { if (!initialized) { throw new IllegalStateException("Cipher not initialized"); } if (opmode != Cipher.UNWRAP_MODE) { throw new IllegalStateException("Cipher not initialized " + "for unwrapping keys"); } } if ((wrappedKeyType != SECRET_KEY) && (wrappedKeyType != PRIVATE_KEY) && (wrappedKeyType != PUBLIC_KEY)) { throw new InvalidParameterException("Invalid key type"); } chooseFirstProvider(); return spi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType); } private AlgorithmParameterSpec getAlgorithmParameterSpec( AlgorithmParameters params) throws InvalidParameterSpecException { if (params == null) { return null; } String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH); if (alg.equalsIgnoreCase("RC2")) { return params.getParameterSpec(RC2ParameterSpec.class); } if (alg.equalsIgnoreCase("RC5")) { return params.getParameterSpec(RC5ParameterSpec.class); } if (alg.startsWith("PBE")) { return params.getParameterSpec(PBEParameterSpec.class); } if (alg.startsWith("DES")) { return params.getParameterSpec(IvParameterSpec.class); } return null; } private static CryptoPermission getConfiguredPermission( String transformation) throws NullPointerException, NoSuchAlgorithmException { if (transformation == null) throw new NullPointerException();Lines 2001–2500 of 2677. Previous lines Load more
* @param outputOffset the offset in <code>output</code> where the result * is stored * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] output, int outputOffset) throws IllegalBlockSizeException, ShortBufferException, BadPaddingException { checkCipherState(); // Input sanity check if ((output == null) || (outputOffset < 0)) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(null, 0, 0, output, outputOffset); } /** * 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 initialized. * * <p>The bytes in the <code>input</code> buffer, and any input bytes that * may have been buffered during a previous <code>update</code> operation, * are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in a new buffer. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * @param input the input buffer * * @return the new buffer with the result * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null) { throw new IllegalArgumentException("Null input buffer"); } chooseFirstProvider(); return spi.engineDoFinal(input, 0, input.length); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous <code>update</code> * operation, are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in a new buffer. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * * @return the new buffer with the result * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous <code>update</code> * operation, are processed, with padding (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the <code>output</code> buffer. * * <p>If the <code>output</code> buffer is too small to hold the result, * a <code>ShortBufferException</code> is thrown. In this case, repeat this * call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * @param output the buffer for the result * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen, output, 0); } /** * 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 initialized. * * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code> inclusive, and any input * bytes that may have been buffered during a previous * <code>update</code> operation, are processed, with padding * (if requested) being applied. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the <code>output</code> buffer, starting at * <code>outputOffset</code> inclusive. * * <p>If the <code>output</code> buffer is too small to hold the result, * a <code>ShortBufferException</code> is thrown. In this case, repeat this * call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * starts * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in <code>output</code> where the result * is stored * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if the given output buffer is too small * to hold the result * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value */ public final int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); // Input sanity check if (input == null || inputOffset < 0 || inputLen > (input.length - inputOffset) || inputLen < 0 || outputOffset < 0) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(input, inputOffset, inputLen, output, outputOffset); } /** * 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 initialized. * * <p>All <code>input.remaining()</code> bytes starting at * <code>input.position()</code> are processed. * If an AEAD mode such as GCM/CCM is being used, the authentication * tag is appended in the case of encryption, or verified in the * case of decryption. * The result is stored in the output buffer. * Upon return, the input buffer's position will be equal * to its limit; its limit will not have changed. The output buffer's * position will have advanced by n, where n is the value returned * by this method; the output buffer's limit will not have changed. * * <p>If <code>output.remaining()</code> bytes are insufficient to * hold the result, a <code>ShortBufferException</code> is thrown. * In this case, repeat this call with a larger output buffer. Use * {@link #getOutputSize(int) getOutputSize} to determine how big * the output buffer should be. * * <p>Upon finishing, this method resets this cipher object to the state * it was in when previously initialized via a call to <code>init</code>. * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to * <code>init</code>) more data. * * <p>Note: if any exception is thrown, this cipher object may need to * be reset before it can be used again. * * <p>Note: this method should be copy-safe, which means the * <code>input</code> and <code>output</code> buffers can reference * the same byte array and no unprocessed input data is overwritten * when the result is copied into the output buffer. * * @param input the input ByteBuffer * @param output the output ByteBuffer * * @return the number of bytes stored in <code>output</code> * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * @exception IllegalArgumentException if input and output are the * same object * @exception ReadOnlyBufferException if the output buffer is read-only * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * block size; or if this encryption algorithm is unable to * process the input data provided. * @exception ShortBufferException if there is insufficient space in the * output buffer * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * @exception AEADBadTagException if this cipher is decrypting in an * AEAD mode (such as GCM/CCM), and the received authentication tag * does not match the calculated value * * @since 1.5 */ public final int doFinal(ByteBuffer input, ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { checkCipherState(); if ((input == null) || (output == null)) { throw new IllegalArgumentException("Buffers must not be null"); } if (input == output) { throw new IllegalArgumentException("Input and output buffers must " + "not be the same object, consider using buffer.duplicate()"); } if (output.isReadOnly()) { throw new ReadOnlyBufferException(); } chooseFirstProvider(); return spi.engineDoFinal(input, output); } /** * Wrap a key. * * @param key the key to be wrapped. * * @return the wrapped key. * * @exception IllegalStateException if this cipher is in a wrong * state (e.g., has not been initialized). * * @exception IllegalBlockSizeException if this cipher is a block * cipher, no padding has been requested, and the length of the * encoding of the key to be wrapped is not a * multiple of the block size. * * @exception InvalidKeyException if it is impossible or unsafe to * wrap the key with this cipher (e.g., a hardware protected key is * being passed to a software-only cipher). */ public final byte[] wrap(Key key) throws IllegalBlockSizeException, InvalidKeyException { if (!(this instanceof NullCipher)) { if (!initialized) { throw new IllegalStateException("Cipher not initialized"); } if (opmode != Cipher.WRAP_MODE) { throw new IllegalStateException("Cipher not initialized " + "for wrapping keys"); } } chooseFirstProvider(); return spi.engineWrap(key); } /** * Unwrap a previously wrapped key. * * @param wrappedKey the key to be unwrapped. * * @param wrappedKeyAlgorithm the algorithm associated with the wrapped * key. * * @param wrappedKeyType the type of the wrapped key. This must be one of * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or * <code>PUBLIC_KEY</code>. * * @return the unwrapped key. * * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized). * * @exception NoSuchAlgorithmException if no installed providers * can create keys of type <code>wrappedKeyType</code> for the * <code>wrappedKeyAlgorithm</code>. * * @exception InvalidKeyException if <code>wrappedKey</code> does not * represent a wrapped key of type <code>wrappedKeyType</code> for * the <code>wrappedKeyAlgorithm</code>. */ public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { if (!(this instanceof NullCipher)) { if (!initialized) { throw new IllegalStateException("Cipher not initialized"); } if (opmode != Cipher.UNWRAP_MODE) { throw new IllegalStateException("Cipher not initialized " + "for unwrapping keys"); } } if ((wrappedKeyType != SECRET_KEY) && (wrappedKeyType != PRIVATE_KEY) && (wrappedKeyType != PUBLIC_KEY)) { throw new InvalidParameterException("Invalid key type"); } chooseFirstProvider(); return spi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType); } private AlgorithmParameterSpec getAlgorithmParameterSpec( AlgorithmParameters params) throws InvalidParameterSpecException { if (params == null) { return null; } String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH); if (alg.equalsIgnoreCase("RC2")) { return params.getParameterSpec(RC2ParameterSpec.class); } if (alg.equalsIgnoreCase("RC5")) { return params.getParameterSpec(RC5ParameterSpec.class); } if (alg.startsWith("PBE")) { return params.getParameterSpec(PBEParameterSpec.class); } if (alg.startsWith("DES")) { return params.getParameterSpec(IvParameterSpec.class); } return null; } private static CryptoPermission getConfiguredPermission( String transformation) throws NullPointerException, NoSuchAlgorithmException { if (transformation == null) throw new NullPointerException();