PKCS12PBECipherCore(String symmCipherAlg, int defKeySize) throws NoSuchAlgorithmException {

    algo = symmCipherAlg;
    if (algo.equals("RC4")) {
      pbeAlgo = "PBEWithSHA1AndRC4_" + defKeySize * 8;
    } else {
      SymmetricCipher symmCipher = null;
      if (algo.equals("DESede")) {
        symmCipher = new DESedeCrypt();
        pbeAlgo = "PBEWithSHA1AndDESede";
      } else if (algo.equals("RC2")) {
        symmCipher = new RC2Crypt();
        pbeAlgo = "PBEWithSHA1AndRC2_" + defKeySize * 8;
      } else {
        throw new NoSuchAlgorithmException(
            "No Cipher implementation " + "for PBEWithSHA1And" + algo);
      }
      blockSize = symmCipher.getBlockSize();
      cipher = new CipherCore(symmCipher, blockSize);
      cipher.setMode("CBC");
      try {
        cipher.setPadding("PKCS5Padding");
      } catch (NoSuchPaddingException nspe) {
        // should not happen
      }
    }
    keySize = defKeySize;
  }
 int implGetOutputSize(int inLen) {
   return cipher.getOutputSize(inLen);
 }
Example #3
0
 /**
  * Returns the initialization vector (IV) in a new buffer.
  *
  * <p>This is useful in the case where a random IV has been created (see <a href =
  * "#init">init</a>), or in the context of password-based encryption or decryption, where the IV
  * is derived from a user-provided password.
  *
  * @return the initialization vector in a new buffer, or null if the underlying algorithm does not
  *     use an IV, or if the IV has not yet been set.
  */
 protected byte[] engineGetIV() {
   return core.getIV();
 }
Example #4
0
 /**
  * Sets the padding mechanism of this cipher.
  *
  * @param padding the padding mechanism
  * @exception NoSuchPaddingException if the requested padding mechanism does not exist
  */
 protected void engineSetPadding(String paddingScheme) throws NoSuchPaddingException {
   core.setPadding(paddingScheme);
 }
 byte[] implDoFinal(byte[] in, int inOff, int inLen)
     throws IllegalBlockSizeException, BadPaddingException {
   return cipher.doFinal(in, inOff, inLen);
 }
 byte[] implWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
   return cipher.wrap(key);
 }
Example #7
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>, and any input bytes that may have been buffered during a previous <code>
  * update</code> operation, are processed, with padding (if requested) being applied. The result
  * is stored in a new buffer.
  *
  * <p>The cipher is reset to its initial state (uninitialized) after this call.
  *
  * @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 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
  * @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
  */
 protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
     throws IllegalBlockSizeException, BadPaddingException {
   return core.doFinal(input, inputOffset, inputLen);
 }
 byte[] implUpdate(byte[] in, int inOff, int inLen) {
   return cipher.update(in, inOff, inLen);
 }
Example #9
0
 /**
  * Continues a multiple-part encryption or decryption operation (depending on how this cipher was
  * initialized), processing another data part.
  *
  * <p>The first <code>inputLen</code> bytes in the <code>input</code> buffer, starting at <code>
  * inputOffset</code>, are processed, and the result is stored in a new buffer.
  *
  * @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)
  */
 protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
   return core.update(input, inputOffset, inputLen);
 }
Example #10
0
 /**
  * Continues a multiple-part encryption or decryption operation (depending on how this cipher was
  * initialized), processing another data part.
  *
  * <p>The first <code>inputLen</code> bytes in the <code>input</code> buffer, starting at <code>
  * inputOffset</code>, are processed, and the result is stored in the <code>output</code> buffer,
  * starting at <code>outputOffset</code>.
  *
  * @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 ShortBufferException if the given output buffer is too small to hold the result
  */
 protected int engineUpdate(
     byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
     throws ShortBufferException {
   return core.update(input, inputOffset, inputLen, output, outputOffset);
 }
Example #11
0
 protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
     throws InvalidKeyException, InvalidAlgorithmParameterException {
   core.init(opmode, key, params, random);
 }
Example #12
0
 /**
  * Initializes this cipher with a key and a source of randomness.
  *
  * <p>The cipher is initialized for one of the following four operations: encryption, decryption,
  * key wrapping or key unwrapping, depending on the value of <code>opmode</code>.
  *
  * <p>If this cipher requires an initialization vector (IV), it will get it from <code>random
  * </code>. This behaviour should only be used in encryption or key wrapping mode, however. When
  * initializing a cipher that requires an IV for decryption or key unwrapping, the IV (same IV
  * that was used for encryption or key wrapping) must be provided explicitly as a parameter, in
  * order to get the correct result.
  *
  * <p>This method also cleans existing buffer and other related state information.
  *
  * @param opmode the operation mode of this cipher (this is one of the following: <code>
  *     ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code> or <code>UNWRAP_MODE
  *     </code>)
  * @param key the secret key
  * @param random the source of randomness
  * @exception InvalidKeyException if the given key is inappropriate for initializing this cipher
  */
 protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
   core.init(opmode, key, random);
 }
Example #13
0
 /**
  * Returns the parameters used with this cipher.
  *
  * <p>The returned parameters may be the same that were used to initialize this cipher, or may
  * contain the default set of parameters or a set of randomly generated parameters used by the
  * underlying cipher implementation (provided that the underlying cipher implementation uses a
  * default set of parameters or creates new parameters if it needs parameters but was not
  * initialized with any).
  *
  * @return the parameters used with this cipher, or null if this cipher does not use any
  *     parameters.
  */
 protected AlgorithmParameters engineGetParameters() {
   return core.getParameters("DES");
 }
Example #14
0
 byte[] implGetIV() {
   return cipher.getIV();
 }
Example #15
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>, and any input bytes that may have been buffered during a previous <code>
  * update</code> operation, are processed, with padding (if requested) being applied. The result
  * is stored in the <code>output</code> buffer, starting at <code>outputOffset</code>.
  *
  * <p>The cipher is reset to its initial state (uninitialized) after this call.
  *
  * @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 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
  * @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
  */
 protected int engineDoFinal(
     byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
     throws IllegalBlockSizeException, ShortBufferException, BadPaddingException {
   return core.doFinal(input, inputOffset, inputLen, output, outputOffset);
 }
Example #16
0
  void implInit(
      int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random, CipherSpi cipherImpl)
      throws InvalidKeyException, InvalidAlgorithmParameterException {
    char[] passwdChars = null;
    salt = null;
    iCount = 0;
    if (key instanceof javax.crypto.interfaces.PBEKey) {
      javax.crypto.interfaces.PBEKey pbeKey = (javax.crypto.interfaces.PBEKey) key;
      passwdChars = pbeKey.getPassword();
      salt = pbeKey.getSalt(); // maybe null if unspecified
      iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified
    } else if (key instanceof SecretKey) {
      byte[] passwdBytes = key.getEncoded();
      if ((passwdBytes == null) || !(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
        throw new InvalidKeyException("Missing password");
      }
      passwdChars = new char[passwdBytes.length];
      for (int i = 0; i < passwdChars.length; i++) {
        passwdChars[i] = (char) (passwdBytes[i] & 0x7f);
      }
    } else {
      throw new InvalidKeyException("SecretKey of PBE type required");
    }

    if (((opmode == Cipher.DECRYPT_MODE) || (opmode == Cipher.UNWRAP_MODE))
        && ((params == null) && ((salt == null) || (iCount == 0)))) {
      throw new InvalidAlgorithmParameterException("Parameters missing");
    }

    if (params == null) {
      // generate default for salt and iteration count if necessary
      if (salt == null) {
        salt = new byte[DEFAULT_SALT_LENGTH];
        if (random != null) {
          random.nextBytes(salt);
        } else {
          SunJCE.getRandom().nextBytes(salt);
        }
      }
      if (iCount == 0) iCount = DEFAULT_COUNT;
    } else if (!(params instanceof PBEParameterSpec)) {
      throw new InvalidAlgorithmParameterException("PBEParameterSpec type required");
    } else {
      PBEParameterSpec pbeParams = (PBEParameterSpec) params;
      // make sure the parameter values are consistent
      if (salt != null) {
        if (!Arrays.equals(salt, pbeParams.getSalt())) {
          throw new InvalidAlgorithmParameterException(
              "Inconsistent value of salt between key and params");
        }
      } else {
        salt = pbeParams.getSalt();
      }
      if (iCount != 0) {
        if (iCount != pbeParams.getIterationCount()) {
          throw new InvalidAlgorithmParameterException(
              "Different iteration count between key and params");
        }
      } else {
        iCount = pbeParams.getIterationCount();
      }
    }
    // salt is recommended to be ideally as long as the output
    // of the hash function. However, it may be too strict to
    // force this; so instead, we'll just require the minimum
    // salt length to be 8-byte which is what PKCS#5 recommends
    // and openssl does.
    if (salt.length < 8) {
      throw new InvalidAlgorithmParameterException("Salt must be at least 8 bytes long");
    }
    if (iCount <= 0) {
      throw new InvalidAlgorithmParameterException("IterationCount must be a positive number");
    }
    byte[] derivedKey = derive(passwdChars, salt, iCount, keySize, CIPHER_KEY);
    SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);

    if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
      ((ARCFOURCipher) cipherImpl).engineInit(opmode, cipherKey, random);

    } else {
      byte[] derivedIv = derive(passwdChars, salt, iCount, 8, CIPHER_IV);
      IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);

      // initialize the underlying cipher
      cipher.init(opmode, cipherKey, ivSpec, random);
    }
  }
Example #17
0
 /**
  * Wrap a key.
  *
  * @param key the key to be wrapped.
  * @return the wrapped key.
  * @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).
  */
 protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
   return core.wrap(key);
 }
Example #18
0
 int implUpdate(byte[] in, int inOff, int inLen, byte[] out, int outOff)
     throws ShortBufferException {
   return cipher.update(in, inOff, inLen, out, outOff);
 }
Example #19
0
 /**
  * Unwrap a previously wrapped key.
  *
  * @param wrappedKey the key to be unwrapped.
  * @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
  * @param wrappedKeyType the type of the wrapped key. This is one of <code>Cipher.SECRET_KEY
  *     </code>, <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
  * @return the unwrapped key.
  * @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>.
  */
 protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
     throws InvalidKeyException, NoSuchAlgorithmException {
   return core.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
 }
Example #20
0
 int implDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff)
     throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
   return cipher.doFinal(in, inOff, inLen, out, outOff);
 }
Example #21
0
 /**
  * Sets the mode of this cipher.
  *
  * @param mode the cipher mode
  * @exception NoSuchAlgorithmException if the requested cipher mode does not exist
  */
 protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
   core.setMode(mode);
 }
Example #22
0
 Key implUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
     throws InvalidKeyException, NoSuchAlgorithmException {
   return cipher.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
 }
Example #23
0
 /**
  * Returns the length in bytes that an output buffer would need to be in order to hold the result
  * of the next <code>update</code> or <code>doFinal</code> operation, given the input length
  * <code>inputLen</code> (in bytes).
  *
  * <p>This call takes into account any unprocessed (buffered) data from a previous <code>update
  * </code> call, and padding.
  *
  * <p>The actual output length of the next <code>update</code> or <code>doFinal</code> call may be
  * smaller than the length returned by this method.
  *
  * @param inputLen the input length (in bytes)
  * @return the required output buffer size (in bytes)
  */
 protected int engineGetOutputSize(int inputLen) {
   return core.getOutputSize(inputLen);
 }