Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / javax / crypto / Cipher.java
blob2e2d28f7ff4c6ad9b454a5aa3cd242537616ace8
1 /* Cipher.java -- Interface to a cryptographic cipher.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.crypto;
41 import gnu.java.security.Engine;
43 import java.security.AlgorithmParameters;
44 import java.security.InvalidAlgorithmParameterException;
45 import java.security.InvalidKeyException;
46 import java.security.Key;
47 import java.security.NoSuchAlgorithmException;
48 import java.security.NoSuchProviderException;
49 import java.security.Provider;
50 import java.security.SecureRandom;
51 import java.security.Security;
52 import java.security.cert.Certificate;
53 import java.security.cert.X509Certificate;
54 import java.security.spec.AlgorithmParameterSpec;
55 import java.util.StringTokenizer;
57 /**
58 * <p>This class implements a cryptographic cipher for transforming
59 * data.</p>
61 * <p>Ciphers cannot be instantiated directly; rather one of the
62 * <code>getInstance</code> must be used to instantiate a given
63 * <i>transformation</i>, optionally with a specific provider.</p>
65 * <p>A transformation is of the form:</p>
67 * <ul>
68 * <li><i>algorithm</i>/<i>mode</i>/<i>padding</i>, or</li>
69 * <li><i>algorithm</i>
70 * </ul>
72 * <p>where <i>algorithm</i> is the base name of a cryptographic cipher
73 * (such as "AES"), <i>mode</i> is the abbreviated name of a block
74 * cipher mode (such as "CBC" for cipher block chaining mode), and
75 * <i>padding</i> is the name of a padding scheme (such as
76 * "PKCS5Padding"). If only the algorithm name is supplied, then the
77 * provider-specific default mode and padding will be used.</p>
79 * <p>An example transformation is:</p>
81 * <blockquote><code>Cipher c =
82 * Cipher.getInstance("AES/CBC/PKCS5Padding");</code></blockquote>
84 * <p>Finally, when requesting a block cipher in stream cipher mode
85 * (such as <acronym title="Advanced Encryption Standard">AES</acronym>
86 * in OFB or CFB mode) the number of bits to be processed
87 * at a time may be specified by appending it to the name of the mode;
88 * e.g. <code>"AES/OFB8/NoPadding"</code>. If no such number is
89 * specified a provider-specific default value is used.</p>
91 * @author Casey Marshall (csm@gnu.org)
92 * @see java.security.KeyGenerator
93 * @see javax.crypto.SecretKey
95 public class Cipher
98 // Constants and variables.
99 // ------------------------------------------------------------------------
101 private static final String SERVICE = "Cipher";
104 * The decryption operation mode.
106 public static final int DECRYPT_MODE = 2;
109 * The encryption operation mode.
111 public static final int ENCRYPT_MODE = 1;
114 * Constant for when the key to be unwrapped is a private key.
116 public static final int PRIVATE_KEY = 2;
119 * Constant for when the key to be unwrapped is a public key.
121 public static final int PUBLIC_KEY = 1;
124 * Constant for when the key to be unwrapped is a secret key.
126 public static final int SECRET_KEY = 3;
129 * The key unwrapping operation mode.
131 public static final int UNWRAP_MODE = 4;
134 * The key wrapping operation mode.
136 public static final int WRAP_MODE = 3;
139 * The uninitialized state. This state signals that any of the
140 * <code>init</code> methods have not been called, and therefore no
141 * transformations can be done.
143 private static final int INITIAL_STATE = 0;
145 /** The underlying cipher service provider interface. */
146 private CipherSpi cipherSpi;
148 /** The provider from which this instance came. */
149 private Provider provider;
151 /** The transformation requested. */
152 private String transformation;
154 /** Our current state (encrypting, wrapping, etc.) */
155 private int state;
158 // Class methods.
159 // ------------------------------------------------------------------------
162 * <p>Creates a new cipher instance for the given transformation.</p>
164 * <p>The installed providers are tried in order for an
165 * implementation, and the first appropriate instance is returned. If
166 * no installed provider can provide the implementation, an
167 * appropriate exception is thrown.</p>
169 * @param transformation The transformation to create.
170 * @return An appropriate cipher for this transformation.
171 * @throws java.security.NoSuchAlgorithmException If no installed
172 * provider can supply the appropriate cipher or mode.
173 * @throws javax.crypto.NoSuchPaddingException If no installed
174 * provider can supply the appropriate padding.
176 public static final Cipher getInstance(String transformation)
177 throws NoSuchAlgorithmException, NoSuchPaddingException
179 Provider[] providers = Security.getProviders();
180 NoSuchPaddingException ex = null;
181 String msg = "";
182 for (int i = 0; i < providers.length; i++)
186 return getInstance(transformation, providers[i]);
188 catch (NoSuchAlgorithmException nsae)
190 msg = nsae.getMessage();
191 ex = null;
193 catch (NoSuchPaddingException nspe)
195 ex = nspe;
198 if (ex != null)
200 throw ex;
202 throw new NoSuchAlgorithmException(msg);
206 * <p>Creates a new cipher instance for the given transformation and
207 * the named provider.</p>
209 * @param transformation The transformation to create.
210 * @param provider The name of the provider to use.
211 * @return An appropriate cipher for this transformation.
212 * @throws java.security.NoSuchAlgorithmException If the provider cannot
213 * supply the appropriate cipher or mode.
214 * @throws java.security.NoSuchProviderException If the named provider
215 * is not installed.
216 * @throws javax.crypto.NoSuchPaddingException If the provider cannot
217 * supply the appropriate padding.
219 public static final Cipher getInstance(String transformation, String provider)
220 throws NoSuchAlgorithmException, NoSuchProviderException,
221 NoSuchPaddingException
223 Provider p = Security.getProvider(provider);
224 if (p == null)
226 throw new NoSuchProviderException(provider);
228 return getInstance(transformation, p);
232 * Creates a new cipher instance for the given transform and the given
233 * provider.
235 * @param transformation The transformation to create.
236 * @param provider The provider to use.
237 * @return An appropriate cipher for this transformation.
238 * @throws java.security.NoSuchAlgorithmException If the given
239 * provider cannot supply the appropriate cipher or mode.
240 * @throws javax.crypto.NoSuchPaddingException If the given
241 * provider cannot supply the appropriate padding scheme.
243 public static final Cipher getInstance(String transformation, Provider provider)
244 throws NoSuchAlgorithmException, NoSuchPaddingException
246 CipherSpi result = null;
247 String key = null;
248 String alg = null, mode = null, pad = null;
249 String msg = "";
250 if (transformation.indexOf('/') < 0)
254 result = (CipherSpi) Engine.getInstance(SERVICE, transformation,
255 provider);
256 return new Cipher(result, provider, transformation);
258 catch (Exception e)
260 msg = e.getMessage();
263 else
265 StringTokenizer tok = new StringTokenizer(transformation, "/");
266 if (tok.countTokens() != 3)
268 throw new NoSuchAlgorithmException("badly formed transformation");
270 alg = tok.nextToken();
271 mode = tok.nextToken();
272 pad = tok.nextToken();
275 result = (CipherSpi) Engine.getInstance(SERVICE, transformation,
276 provider);
277 return new Cipher(result, provider, transformation);
279 catch (Exception e)
281 msg = e.getMessage();
285 result = (CipherSpi) Engine.getInstance(SERVICE, alg + '/' + mode,
286 provider);
287 result.engineSetPadding(pad);
288 return new Cipher(result, provider, transformation);
290 catch (Exception e)
292 if (e instanceof NoSuchPaddingException)
294 throw (NoSuchPaddingException) e;
296 msg = e.getMessage();
300 result = (CipherSpi) Engine.getInstance(SERVICE, alg + "//" + pad,
301 provider);
302 result.engineSetMode(mode);
303 return new Cipher(result, provider, transformation);
305 catch (Exception e)
307 msg = e.getMessage();
311 result = (CipherSpi) Engine.getInstance(SERVICE, alg, provider);
312 result.engineSetMode(mode);
313 result.engineSetPadding(pad);
314 return new Cipher(result, provider, transformation);
316 catch (Exception e)
318 if (e instanceof NoSuchPaddingException)
320 throw (NoSuchPaddingException) e;
322 msg = e.getMessage();
325 throw new NoSuchAlgorithmException(transformation + ": " + msg);
328 \f// Constructor.
329 // ------------------------------------------------------------------------
332 * Create a cipher.
334 * @param cipherSpi The underlying implementation of the cipher.
335 * @param provider The provider of this cipher implementation.
336 * @param transformation The transformation this cipher performs.
338 protected
339 Cipher(CipherSpi cipherSpi, Provider provider, String transformation)
341 this.cipherSpi = cipherSpi;
342 this.provider = provider;
343 this.transformation = transformation;
344 state = INITIAL_STATE;
347 \f// Public instance methods.
348 // ------------------------------------------------------------------------
351 * Get the name that this cipher instance was created with; this is
352 * equivalent to the "transformation" argument given to any of the
353 * {@link #getInstance()} methods.
355 * @return The cipher name.
357 public final String getAlgorithm()
359 return transformation;
363 * Return the size of blocks, in bytes, that this cipher processes.
365 * @return The block size.
367 public final int getBlockSize()
369 if (cipherSpi != null)
371 return cipherSpi.engineGetBlockSize();
373 return 1;
377 * Return the currently-operating {@link ExemptionMechanism}.
379 * @return null, currently.
381 public final ExemptionMechanism getExemptionMechanism()
383 return null;
387 * Return the <i>initialization vector</i> that this instance was
388 * initialized with.
390 * @return The IV.
392 public final byte[] getIV()
394 if (cipherSpi != null)
396 return cipherSpi.engineGetIV();
398 return null;
402 * Return the {@link java.security.AlgorithmParameters} that this
403 * instance was initialized with.
405 * @return The parameters.
407 public final AlgorithmParameters getParameters()
409 if (cipherSpi != null) {
410 return cipherSpi.engineGetParameters();
412 return null;
416 * Return this cipher's provider.
418 * @return The provider.
420 public final Provider getProvider()
422 return provider;
426 * Finishes a multi-part transformation, and returns the final
427 * transformed bytes.
429 * @return The final transformed bytes.
430 * @throws java.lang.IllegalStateException If this instance has not
431 * been initialized, or if a <tt>doFinal</tt> call has already
432 * been made.
433 * @throws javax.crypto.IllegalBlockSizeException If this instance has
434 * no padding and the input is not a multiple of this cipher's
435 * block size.
436 * @throws javax.crypto.BadPaddingException If this instance is
437 * decrypting and the padding bytes do not match this
438 * instance's padding scheme.
440 public final byte[] doFinal()
441 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException
443 return doFinal(new byte[0], 0, 0);
447 * Finishes a multi-part transformation or does an entire
448 * transformation on the input, and returns the transformed bytes.
450 * @param input The final input bytes.
451 * @return The final transformed bytes.
452 * @throws java.lang.IllegalStateException If this instance has not
453 * been initialized, or if a <tt>doFinal</tt> call has already
454 * been made.
455 * @throws javax.crypto.IllegalBlockSizeException If this instance has
456 * no padding and the input is not a multiple of this cipher's
457 * block size.
458 * @throws javax.crypto.BadPaddingException If this instance is
459 * decrypting and the padding bytes do not match this
460 * instance's padding scheme.
462 public final byte[] doFinal(byte[] input)
463 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException
465 return doFinal(input, 0, input.length);
469 * Finishes a multi-part transformation or does an entire
470 * transformation on the input, and returns the transformed bytes.
472 * @param input The final input bytes.
473 * @param inputOffset The index in the input bytes to start.
474 * @param inputLength The number of bytes to read from the input.
475 * @return The final transformed bytes.
476 * @throws java.lang.IllegalStateException If this instance has not
477 * been initialized, or if a <tt>doFinal</tt> call has already
478 * been made.
479 * @throws javax.crypto.IllegalBlockSizeException If this instance has
480 * no padding and the input is not a multiple of this cipher's
481 * block size.
482 * @throws javax.crypto.BadPaddingException If this instance is
483 * decrypting and the padding bytes do not match this
484 * instance's padding scheme.
486 public final byte[] doFinal(byte[] input, int inputOffset, int inputLength)
487 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException
489 if (cipherSpi == null)
491 byte[] b = new byte[inputLength];
492 System.arraycopy(input, inputOffset, b, 0, inputLength);
493 return b;
495 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
497 throw new IllegalStateException("neither encrypting nor decrypting");
499 state = INITIAL_STATE;
500 return cipherSpi.engineDoFinal(input, inputOffset, inputLength);
504 * Finishes a multi-part transformation and stores the transformed
505 * bytes into the given array.
507 * @param output The destination for the transformed bytes.
508 * @param outputOffset The offset in <tt>output</tt> to start storing
509 * bytes.
510 * @return The number of bytes placed into the output array.
511 * @throws java.lang.IllegalStateException If this instance has not
512 * been initialized, or if a <tt>doFinal</tt> call has already
513 * been made.
514 * @throws javax.crypto.IllegalBlockSizeException If this instance has
515 * no padding and the input is not a multiple of this cipher's
516 * block size.
517 * @throws javax.crypto.BadPaddingException If this instance is
518 * decrypting and the padding bytes do not match this
519 * instance's padding scheme.
520 * @throws javax.crypto.ShortBufferException If the output array is
521 * not large enough to hold the transformed bytes.
523 public final int doFinal(byte[] output, int outputOffset)
524 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException,
525 ShortBufferException
527 if (cipherSpi == null)
529 return 0;
531 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
533 throw new IllegalStateException("neither encrypting nor decrypting");
535 state = INITIAL_STATE;
536 return cipherSpi.engineDoFinal(new byte[0], 0, 0, output, outputOffset);
540 * Finishes a multi-part transformation or transforms a portion of a
541 * byte array, and stores the result in the given byte array.
543 * @param input The input bytes.
544 * @param inputOffset The index in <tt>input</tt> to start.
545 * @param inputLength The number of bytes to transform.
546 * @param output The output buffer.
547 * @param outputOffset The index in <tt>output</tt> to start.
548 * @return The number of bytes placed into the output array.
549 * @throws java.lang.IllegalStateException If this instance has not
550 * been initialized, or if a <tt>doFinal</tt> call has already
551 * been made.
552 * @throws javax.crypto.IllegalBlockSizeException If this instance has
553 * no padding and the input is not a multiple of this cipher's
554 * block size.
555 * @throws javax.crypto.BadPaddingException If this instance is
556 * decrypting and the padding bytes do not match this
557 * instance's padding scheme.
558 * @throws javax.crypto.ShortBufferException If the output array is
559 * not large enough to hold the transformed bytes.
561 public final int doFinal(byte[] input, int inputOffset, int inputLength,
562 byte[] output, int outputOffset)
563 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException,
564 ShortBufferException
566 if (cipherSpi == null)
568 if (inputLength > output.length - outputOffset)
570 throw new ShortBufferException();
572 System.arraycopy(input, inputOffset, output, outputOffset, inputLength);
573 return inputLength;
575 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
577 throw new IllegalStateException("neither encrypting nor decrypting");
579 state = INITIAL_STATE;
580 return cipherSpi.engineDoFinal(input, inputOffset, inputLength,
581 output, outputOffset);
584 public final int doFinal(byte[] input, int inputOffset, int inputLength,
585 byte[] output)
586 throws IllegalStateException, IllegalBlockSizeException, BadPaddingException,
587 ShortBufferException
589 return doFinal(input, inputOffset, inputLength, output, 0);
593 * Returns the size an output buffer needs to be if this cipher is
594 * updated with a number of bytes.
596 * @param inputLength The input length.
597 * @return The output length given this input length.
598 * @throws java.lang.IllegalStateException If this instance has not
599 * been initialized, or if a <tt>doFinal</tt> call has already
600 * been made.
602 public final int getOutputSize(int inputLength) throws IllegalStateException
604 if (cipherSpi == null)
606 return inputLength;
608 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
610 throw new IllegalStateException("neither encrypting nor decrypting");
612 return cipherSpi.engineGetOutputSize(inputLength);
616 * <p>Initialize this cipher with the public key from the given
617 * certificate.</p>
619 * <p>The cipher will be initialized for encryption, decryption, key
620 * wrapping, or key unwrapping, depending upon whether the
621 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
622 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
623 * respectively.</p>
625 * <p>As per the Java 1.4 specification, if <code>cert</code> is an
626 * instance of an {@link java.security.cert.X509Certificate} and its
627 * <i>key usage</i> extension field is incompatible with
628 * <code>opmode</code> then an {@link
629 * java.security.InvalidKeyException} is thrown.</p>
631 * <p>If this cipher requires any random bytes (for example for an
632 * initilization vector) than the {@link java.security.SecureRandom}
633 * with the highest priority is used as the source of these bytes.</p>
635 * <p>A call to any of the <code>init</code> methods overrides the
636 * state of the instance, and is equivalent to creating a new instance
637 * and calling its <code>init</code> method.</p>
639 * @param opmode The operation mode to use.
640 * @param certificate The certificate.
641 * @throws java.security.InvalidKeyException If the underlying cipher
642 * instance rejects the certificate's public key, or if the
643 * public key cannot be used as described above.
645 public final void init(int opmode, Certificate certificate)
646 throws InvalidKeyException
648 init(opmode, certificate, new SecureRandom());
652 * <p>Initialize this cipher with the supplied key.</p>
654 * <p>The cipher will be initialized for encryption, decryption, key
655 * wrapping, or key unwrapping, depending upon whether the
656 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
657 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
658 * respectively.</p>
660 * <p>If this cipher requires any random bytes (for example for an
661 * initilization vector) than the {@link java.security.SecureRandom}
662 * with the highest priority is used as the source of these bytes.</p>
664 * <p>A call to any of the <code>init</code> methods overrides the
665 * state of the instance, and is equivalent to creating a new instance
666 * and calling its <code>init</code> method.</p>
668 * @param opmode The operation mode to use.
669 * @param key The key.
670 * @throws java.security.InvalidKeyException If the underlying cipher
671 * instance rejects the given key.
673 public final void init(int opmode, Key key) throws InvalidKeyException
675 state = opmode;
676 if (cipherSpi != null)
678 cipherSpi.engineInit(opmode, key, new SecureRandom());
683 * <p>Initialize this cipher with the public key from the given
684 * certificate and the specified source of randomness.</p>
686 * <p>The cipher will be initialized for encryption, decryption, key
687 * wrapping, or key unwrapping, depending upon whether the
688 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
689 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
690 * respectively.</p>
692 * <p>As per the Java 1.4 specification, if <code>cert</code> is an
693 * instance of an {@link java.security.cert.X509Certificate} and its
694 * <i>key usage</i> extension field is incompatible with
695 * <code>opmode</code> then an {@link
696 * java.security.InvalidKeyException} is thrown.</p>
698 * <p>If this cipher requires any random bytes (for example for an
699 * initilization vector) than the {@link java.security.SecureRandom}
700 * with the highest priority is used as the source of these bytes.</p>
702 * <p>A call to any of the <code>init</code> methods overrides the
703 * state of the instance, and is equivalent to creating a new instance
704 * and calling its <code>init</code> method.</p>
706 * @param opmode The operation mode to use.
707 * @param certificate The certificate.
708 * @param random The source of randomness.
709 * @throws java.security.InvalidKeyException If the underlying cipher
710 * instance rejects the certificate's public key, or if the
711 * public key cannot be used as described above.
713 public final void
714 init(int opmode, Certificate certificate, SecureRandom random)
715 throws InvalidKeyException
717 if (certificate instanceof X509Certificate)
719 boolean[] keyInfo = ((X509Certificate) certificate).getKeyUsage();
720 if (keyInfo != null)
722 switch (opmode)
724 case DECRYPT_MODE:
725 if (!keyInfo[3])
727 throw new InvalidKeyException(
728 "the certificate's key cannot be used for transforming data");
730 if (keyInfo[7])
732 throw new InvalidKeyException(
733 "the certificate's key can only be used for encryption");
735 break;
737 case ENCRYPT_MODE:
738 if (!keyInfo[3])
740 throw new InvalidKeyException(
741 "the certificate's key cannot be used for transforming data");
743 if (keyInfo[8])
745 throw new InvalidKeyException(
746 "the certificate's key can only be used for decryption");
748 break;
750 case UNWRAP_MODE:
751 if (!keyInfo[2] || keyInfo[7])
753 throw new InvalidKeyException(
754 "the certificate's key cannot be used for key unwrapping");
756 break;
758 case WRAP_MODE:
759 if (!keyInfo[2] || keyInfo[8])
761 throw new InvalidKeyException(
762 "the certificate's key cannot be used for key wrapping");
764 break;
768 init(opmode, certificate.getPublicKey(), random);
772 * <p>Initialize this cipher with the supplied key and source of
773 * randomness.</p>
775 * <p>The cipher will be initialized for encryption, decryption, key
776 * wrapping, or key unwrapping, depending upon whether the
777 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
778 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
779 * respectively.</p>
781 * <p>A call to any of the <code>init</code> methods overrides the
782 * state of the instance, and is equivalent to creating a new instance
783 * and calling its <code>init</code> method.</p>
785 * @param opmode The operation mode to use.
786 * @param key The key.
787 * @param random The source of randomness to use.
788 * @throws java.security.InvalidKeyException If the underlying cipher
789 * instance rejects the given key.
791 public final void init(int opmode, Key key, SecureRandom random)
792 throws InvalidKeyException
794 state = opmode;
795 if (cipherSpi != null)
797 cipherSpi.engineInit(opmode, key, random);
802 * <p>Initialize this cipher with the supplied key and parameters.</p>
804 * <p>The cipher will be initialized for encryption, decryption, key
805 * wrapping, or key unwrapping, depending upon whether the
806 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
807 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
808 * respectively.</p>
810 * <p>If this cipher requires any random bytes (for example for an
811 * initilization vector) then the {@link java.security.SecureRandom}
812 * with the highest priority is used as the source of these bytes.</p>
814 * <p>A call to any of the <code>init</code> methods overrides the
815 * state of the instance, and is equivalent to creating a new instance
816 * and calling its <code>init</code> method.</p>
818 * @param opmode The operation mode to use.
819 * @param key The key.
820 * @param params The algorithm parameters to initialize this instance
821 * with.
822 * @throws java.security.InvalidKeyException If the underlying cipher
823 * instance rejects the given key.
824 * @throws java.security.InvalidAlgorithmParameterException If the
825 * supplied parameters are inappropriate for this cipher.
827 public final void init(int opmode, Key key, AlgorithmParameters params)
828 throws InvalidKeyException, InvalidAlgorithmParameterException
830 init(opmode, key, params, new SecureRandom());
834 * <p>Initialize this cipher with the supplied key and parameters.</p>
836 * <p>The cipher will be initialized for encryption, decryption, key
837 * wrapping, or key unwrapping, depending upon whether the
838 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
839 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
840 * respectively.</p>
842 * <p>If this cipher requires any random bytes (for example for an
843 * initilization vector) then the {@link java.security.SecureRandom}
844 * with the highest priority is used as the source of these bytes.</p>
846 * <p>A call to any of the <code>init</code> methods overrides the
847 * state of the instance, and is equivalent to creating a new instance
848 * and calling its <code>init</code> method.</p>
850 * @param opmode The operation mode to use.
851 * @param key The key.
852 * @param params The algorithm parameters to initialize this instance
853 * with.
854 * @throws java.security.InvalidKeyException If the underlying cipher
855 * instance rejects the given key.
856 * @throws java.security.InvalidAlgorithmParameterException If the
857 * supplied parameters are inappropriate for this cipher.
859 public final void init(int opmode, Key key, AlgorithmParameterSpec params)
860 throws InvalidKeyException, InvalidAlgorithmParameterException
862 init(opmode, key, params, new SecureRandom());
866 * <p>Initialize this cipher with the supplied key, parameters, and
867 * source of randomness.</p>
869 * <p>The cipher will be initialized for encryption, decryption, key
870 * wrapping, or key unwrapping, depending upon whether the
871 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
872 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
873 * respectively.</p>
875 * <p>A call to any of the <code>init</code> methods overrides the
876 * state of the instance, and is equivalent to creating a new instance
877 * and calling its <code>init</code> method.</p>
879 * @param opmode The operation mode to use.
880 * @param key The key.
881 * @param params The algorithm parameters to initialize this instance
882 * with.
883 * @param random The source of randomness to use.
884 * @throws java.security.InvalidKeyException If the underlying cipher
885 * instance rejects the given key.
886 * @throws java.security.InvalidAlgorithmParameterException If the
887 * supplied parameters are inappropriate for this cipher.
889 public final void init(int opmode, Key key, AlgorithmParameters params,
890 SecureRandom random)
891 throws InvalidKeyException, InvalidAlgorithmParameterException
893 state = opmode;
894 if (cipherSpi != null)
896 cipherSpi.engineInit(opmode, key, params, random);
901 * <p>Initialize this cipher with the supplied key, parameters, and
902 * source of randomness.</p>
904 * <p>The cipher will be initialized for encryption, decryption, key
905 * wrapping, or key unwrapping, depending upon whether the
906 * <code>opmode</code> argument is {@link #ENCRYPT_MODE}, {@link
907 * #DECRYPT_MODE}, {@link #WRAP_MODE}, or {@link #UNWRAP_MODE},
908 * respectively.</p>
910 * <p>A call to any of the <code>init</code> methods overrides the
911 * state of the instance, and is equivalent to creating a new instance
912 * and calling its <code>init</code> method.</p>
914 * @param opmode The operation mode to use.
915 * @param key The key.
916 * @param params The algorithm parameters to initialize this instance
917 * with.
918 * @param random The source of randomness to use.
919 * @throws java.security.InvalidKeyException If the underlying cipher
920 * instance rejects the given key.
921 * @throws java.security.InvalidAlgorithmParameterException If the
922 * supplied parameters are inappropriate for this cipher.
924 public final void init(int opmode, Key key, AlgorithmParameterSpec params,
925 SecureRandom random)
926 throws InvalidKeyException, InvalidAlgorithmParameterException
928 state = opmode;
929 if (cipherSpi != null)
931 cipherSpi.engineInit(opmode, key, params, random);
936 * Unwrap a previously-wrapped key.
938 * @param wrappedKey The wrapped key.
939 * @param wrappedKeyAlgorithm The algorithm with which the key was
940 * wrapped.
941 * @param wrappedKeyType The type of key (public, private, or
942 * secret) that this wrapped key respresents.
943 * @return The unwrapped key.
944 * @throws java.lang.IllegalStateException If this instance has not be
945 * initialized for unwrapping.
946 * @throws java.security.InvalidKeyException If <code>wrappedKey</code>
947 * is not a wrapped key, if the algorithm cannot unwrap this
948 * key, or if the unwrapped key's type differs from the
949 * specified type.
950 * @throws java.security.NoSuchAlgorithmException If
951 * <code>wrappedKeyAlgorithm</code> is not a valid algorithm
952 * name.
954 public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
955 int wrappedKeyType)
956 throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException
958 if (cipherSpi == null)
960 return null;
962 if (state != UNWRAP_MODE)
964 throw new IllegalStateException("instance is not for unwrapping");
966 return cipherSpi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
967 wrappedKeyType);
971 * Continue a multi-part transformation on an entire byte array,
972 * returning the transformed bytes.
974 * @param input The input bytes.
975 * @return The transformed bytes.
976 * @throws java.lang.IllegalStateException If this cipher was not
977 * initialized for encryption or decryption.
979 public final byte[] update(byte[] input) throws IllegalStateException
981 return update(input, 0, input.length);
985 * Continue a multi-part transformation on part of a byte array,
986 * returning the transformed bytes.
988 * @param input The input bytes.
989 * @param inputOffset The index in the input to start.
990 * @param inputLength The number of bytes to transform.
991 * @return The transformed bytes.
992 * @throws java.lang.IllegalStateException If this cipher was not
993 * initialized for encryption or decryption.
995 public final byte[] update(byte[] input, int inputOffset, int inputLength)
996 throws IllegalStateException
998 if (cipherSpi == null)
1000 byte[] b = new byte[inputLength];
1001 System.arraycopy(input, inputOffset, b, 0, inputLength);
1002 return b;
1004 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
1006 throw new IllegalStateException(
1007 "cipher is not for encrypting or decrypting");
1009 return cipherSpi.engineUpdate(input, inputOffset, inputLength);
1013 * Continue a multi-part transformation on part of a byte array,
1014 * placing the transformed bytes into the given array.
1016 * @param input The input bytes.
1017 * @param inputOffset The index in the input to start.
1018 * @param inputLength The number of bytes to transform.
1019 * @param output The output byte array.
1020 * @return The number of transformed bytes.
1021 * @throws java.lang.IllegalStateException If this cipher was not
1022 * initialized for encryption or decryption.
1023 * @throws javax.security.ShortBufferException If there is not enough
1024 * room in the output array to hold the transformed bytes.
1026 public final int update(byte[] input, int inputOffset, int inputLength,
1027 byte[] output)
1028 throws IllegalStateException, ShortBufferException
1030 return update(input, inputOffset, inputLength, output, 0);
1034 * Continue a multi-part transformation on part of a byte array,
1035 * placing the transformed bytes into the given array.
1037 * @param input The input bytes.
1038 * @param inputOffset The index in the input to start.
1039 * @param inputLength The number of bytes to transform.
1040 * @param output The output byte array.
1041 * @param outputOffset The index in the output array to start.
1042 * @return The number of transformed bytes.
1043 * @throws java.lang.IllegalStateException If this cipher was not
1044 * initialized for encryption or decryption.
1045 * @throws javax.security.ShortBufferException If there is not enough
1046 * room in the output array to hold the transformed bytes.
1048 public final int update(byte[] input, int inputOffset, int inputLength,
1049 byte[] output, int outputOffset)
1050 throws IllegalStateException, ShortBufferException
1052 if (cipherSpi == null)
1054 if (inputLength > output.length - outputOffset)
1056 throw new ShortBufferException();
1058 System.arraycopy(input, inputOffset, output, outputOffset, inputLength);
1059 return inputLength;
1061 if (state != ENCRYPT_MODE && state != DECRYPT_MODE)
1063 throw new IllegalStateException(
1064 "cipher is not for encrypting or decrypting");
1066 return cipherSpi.engineUpdate(input, inputOffset, inputLength,
1067 output, outputOffset);
1071 * Wrap a key.
1073 * @param key The key to wrap.
1074 * @return The wrapped key.
1075 * @throws java.lang.IllegalStateException If this instance was not
1076 * initialized for key wrapping.
1077 * @throws javax.crypto.IllegalBlockSizeException If this instance has
1078 * no padding and the key is not a multiple of the block size.
1079 * @throws java.security.InvalidKeyException If this instance cannot
1080 * wrap this key.
1082 public final byte[] wrap(Key key)
1083 throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException
1085 if (cipherSpi == null)
1087 return null;
1089 if (state != WRAP_MODE)
1091 throw new IllegalStateException("instance is not for key wrapping");
1093 return cipherSpi.engineWrap(key);