/**
   * This method returns a EncryptedData structure with all the necessary information to allow
   * storage in database. Encryted data is stored in file system without defined file name. Returned
   * data must be treated in this way:
   *
   * <ul>
   *   <li>key must be stored NOWHERE, only must exist in the shared URL
   *   <li>id, encryptedPath and encryptedName must be stored in database
   * </ul>
   *
   * With this data this methods builds a NEW KEY based on seed and applying the provided key. KEY
   * is the provided key and must be regenerated in each method invocation (one-time use). ID is the
   * encrypted seed, using the generated NEW KEY and an initialization vector based on seed itself,
   * built by #getIv(String). PATH and NAME is encrypted with the same IV and NEW KEY as the ID.
   * With this protocol we are trying to avoid the possibility of recovering encrypted data because
   * the original key is never stored, only the owner of the shared URL has such key. So if the
   * server is compromised by an attacker, this one could not discover the path of a file associated
   * to a database record or decrypt a file content (because the lack of keys).
   *
   * @param content conted to be encrypted
   * @param name file name
   * @param seed value used to genererate the AES Initialization Vector
   * @param key AES key used for encryption
   * @return struct with reference info of encryptation result
   * @throws IOException
   * @throws FileNotFoundException
   */
  protected EncryptedData doEncryptContent(
      InputStream content, String name, String seed, byte[] key)
      throws IOException, FileNotFoundException {

    byte[] iv = getIv(seed);

    byte[] encryptedIv = cryptoHelper.encryptIv(iv, key);
    byte[] newKey =
        Arrays.copyOf(
            encryptedIv,
            CryptoHelper.KEY_LENGTH
                / 8); // only first key size bytes (from a 16 bytes iv, the encrypted data is
                      // 128+128, being last 128 padding data

    InputStream encryptedStream = cryptoHelper.encrypt(content, iv, newKey);

    String targetDirPath = getTargetDirPath();
    File targetFile = getTargetFile(targetDirPath);

    FileOutputStream fos = new FileOutputStream(targetFile);
    IOUtils.copyLarge(encryptedStream, fos, new byte[512]);

    byte[] id = encryptString(seed, iv, newKey);
    byte[] encryptedPath = encryptString(targetFile.getPath(), iv, newKey);
    byte[] encryptedName = encryptString(name, iv, newKey);

    EncryptedData ed = new EncryptedData();
    ed.setKey(key);
    ed.setId(id);
    ed.setEncryptedPath(encryptedPath);
    ed.setEncryptedName(encryptedName);

    return ed;
  }
 protected byte[] encryptString(String s, byte[] iv, byte[] key)
     throws IOException, UnsupportedEncodingException {
   InputStream encryptedStream =
       cryptoHelper.encrypt(new ByteArrayInputStream(s.getBytes("utf-8")), iv, key);
   return IOUtils.toByteArray(encryptedStream);
 }