- added integration test wiht maven, ant
- updated docs
- bugfixes

git-svn-id: https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/yaafi-crypto@1880073 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index bef15db..bb8e321 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,13 +70,30 @@
 
   <dependencies>
     <!-- testing dependencies -->
-    <dependency>
-      <!-- to gt junit 5 -->
-      <groupId>org.apache.fulcrum</groupId>
-      <artifactId>fulcrum-testcontainer</artifactId>
-      <version>1.0.9-SNAPSHOT</version>
-      <scope>test</scope>
-    </dependency>
+       <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>5.6.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.13</version>
+              <scope>test</scope>
+		</dependency>
+        <dependency>
+            <groupId>org.apache.fulcrum</groupId>
+            <artifactId>fulcrum-testcontainer</artifactId>
+            <version>1.0.8</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>test</scope>
+      </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
@@ -88,7 +105,7 @@
         <artifactId>commons-io</artifactId>
         <version>2.6</version>
         <scope>test</scope>
-    </dependency>
+    </dependency>    
   </dependencies>
 
   <build>
@@ -97,10 +114,99 @@
     <testResources>
       <testResource>
         <directory>src/test</directory>
-        <includes> <include>**/*.xml</include>
+        <includes> <include>**/*.xml</include><include>**/*.properties</include>
         </includes>
+        <filtering>true</filtering>
       </testResource>
     </testResources>
+    
+    <!-- only needed for integration-test and manifest class testing -->
+    <filters>
+      <filter>${basedir}/src/filters/filter-integration-test.properties</filter>
+    </filters>
+    
+    <plugins>
+     <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3</version>
+        <configuration>
+          <archive>
+            <manifest>
+              <addClasspath>true</addClasspath>
+              <mainClass>org.apache.fulcrum.jce.crypto.cli.CLI2</mainClass>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>    
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <!-- 
+            Integration Test encrypts and decrypts in one step
+            mvn clean install integration-test 
+            -->
+        <executions>
+          <execution>
+            <id>init</id>
+            <phase>integration-test</phase>
+            <configuration>
+              <skip>${skip.pw.encrypt}</skip>
+              <target>
+                <ant
+                  antfile="${basedir}/src/ant/integration-test-build-pw.xml"
+                  target="init">
+                  <property name="build.path"
+                    value="${basedir}/build" />
+                   <property name="password" value="${test.password}" />
+                  <property name="meta.pw" value="${meta.pw}" />
+                  <property name="jarname" value="${project.build.finalName}" />
+                  <!-- generates encrypted password, saved in vcs: -->
+                  <property name="target.property.path"
+                    value="${basedir}/src/filters/filter-integration-test.properties" />
+                </ant>
+              </target>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>build</id>
+            <!-- 
+            1) run mvn package to generate executable jar 
+            2) mvn generate-sources -Dskip.pw.gen=false 
+            to generate encrypted password 
+            -->
+            <phase>integration-test</phase>
+            <configuration>
+              <skip>${skip.pw.gen}</skip>
+              <target>
+              <touch file="${basedir}/target/integration-test/filtered-pw.properties" mkdirs="true" />
+                <ant
+                  antfile="${basedir}/src/ant/integration-test-build-pw.xml"
+                  target="build">
+                  <property name="build.path"
+                    value="${basedir}/build" />
+                  <property name="meta.pw" value="${meta.pw}" /><!-- 
+                    provided by env variable -->
+                  <property name="jarname" value="${project.build.finalName}" />
+                  <!-- contains encrypted password, saved in vcs: -->
+                  <property name="source.property.path"
+                    value="${basedir}/src/filters/filter-integration-test.properties" />
+                  <!-- should not be saved in vcs: -->
+                  <property name="target.property.path"
+                    value="${basedir}/target/integration-test/filtered-pw.properties" />
+                </ant>
+              </target>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+
+        </executions>
+      </plugin>
+    </plugins>
   </build>
   
   <properties>
@@ -108,6 +214,11 @@
     <turbine.scmPubCheckoutDirectory>${turbine.site.cache}/fulcrum/yaafi-crypto</turbine.scmPubCheckoutDirectory>
     <turbine.site.cache>${project.build.directory}/turbine-sites</turbine.site.cache>
     <siteContent.path>${project.build.directory}/staging</siteContent.path><!-- default stagingSiteURL -->
+
+    <skip.pw.encrypt>false</skip.pw.encrypt>
+    <skip.pw.gen>false</skip.pw.gen>
+    <meta.pw>changeit</meta.pw>
+    <test.password>mypassword</test.password>
   </properties>  
 	
 </project>
diff --git a/src/ant/integration-test-build-pw.xml b/src/ant/integration-test-build-pw.xml
new file mode 100644
index 0000000..3a8ae02
--- /dev/null
+++ b/src/ant/integration-test-build-pw.xml
@@ -0,0 +1,69 @@
+<project basedir="."  default="build" name="build">

+  <property environment="env"/>

+   <property file=".build"/>  

+   <!-- reading from the file properties: password_encrypted or password -->

+   <property file="${source.property.path}"/>

+   <property name="meta.pw" value="${env.meta.pw}"/>

+

+   <target name="testjava">

+      <echo>Ant Java/JVM  version: ${java.version}</echo> 

+    </target>

+   

+   <target name="decrypt">

+      <echo message="executing java -jar target/${jarname}.jar string dec &quot;${meta.pw}&quot; &quot;${password_encrypted}&quot;."/>

+      <java jar="target/${jarname}.jar" fork="true" failonerror="true" maxmemory="128m" dir="${build.path}/../" outputproperty="decoded.pw" inputstring="">

+         <arg value="string"/>

+         <arg value="dec"/>

+         <arg value="${meta.pw}"/>

+         <arg value="${password_encrypted}"/>

+         <classpath>

+            <pathelement location="target/${jarname}.jar"/>

+            <pathelement path="${java.class.path}"/>

+        </classpath>

+      </java>

+    </target>

+    

+     <target name="encrypt">

+      <echo message="executing java -jar target/${jarname}.jar string enc &quot;${meta.pw}&quot; &quot;${password}&quot;"/>

+      <java jar="target/${jarname}.jar" fork="true" failonerror="true" maxmemory="128m" dir="${build.path}/../" outputproperty="encoded.pw" inputstring="">

+         <arg value="string"/>

+         <arg value="enc"/>

+         <arg value="${meta.pw}"/>

+         <arg value="${password}"/>

+         <classpath>

+            <pathelement location="target/${jarname}.jar"/>

+            <pathelement path="${java.class.path}"/>

+        </classpath>

+      </java>

+    </target>

+  

+   <target name="update">

+       <echo message="updating password in property file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password" value="${decoded.pw}"/>

+        </propertyfile>

+    </target>

+    

+    <target name="init-update">

+       <echo message="updating password_encrypted in property file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password_encrypted" value="${encoded.pw}"/>

+        </propertyfile>

+    </target>

+  

+  <target name="clean">

+   <echo message="cleaning up key password in property file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password" value=""/>

+        </propertyfile>

+  </target>

+  

+    <!-- decrypt to --> 

+   <target name="build" depends="testjava, decrypt, update">

+  </target>

+  

+    <!-- encrypt to password_encrypted -->

+    <target name="init" depends="testjava, encrypt, init-update">

+  </target>

+  

+ </project>  
\ No newline at end of file
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5c970f3..35ed3d8 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -26,7 +26,7 @@
   <body>
     <release version="1.0.8" date="as in SVN">
       <action dev="gk" type="update">
-        Added two Java 8 implementations based on PBE (PBEWithHmacSHA256AndAES_128) or GCM (AES/GCM/NoPadding) encryption.
+        Added two Java 8 implementations based on PBE/AES (PBEWithHmacSHA256AndAES_256) or GCM (AES/GCM/NoPadding) encryption.
       </action>
       <action dev="painter" type="update">
         Clean up PMD and FindBug reports.  Fixed some typos and updated to conform with Turbine coding style guidelines
diff --git a/src/filters/filter-integration-test.properties b/src/filters/filter-integration-test.properties
new file mode 100644
index 0000000..f49b270
--- /dev/null
+++ b/src/filters/filter-integration-test.properties
@@ -0,0 +1,2 @@
+#Mon, 20 Jul 2020 13:46:30 +0200

+password_encrypted=1796bc2d3d02f478bb042ed24740e98a2654fa47bd331266e1a7b682c2d37a2d0254dc61dd71badfe1c22b745f039041

diff --git a/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java b/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
index 8f7de9d..3e27a33 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
@@ -52,7 +52,7 @@
 public class CryptoStreamFactoryImpl extends CryptoStreamFactoryTemplate implements CryptoStreamFactory
 {
     /** the salt for the PBE algorithm */
-    protected byte[] salt;
+    protected final byte[] salt;
 
     /** the count paramter for the PBE algorithm */
     protected int count;
@@ -117,7 +117,7 @@
      */
     public CryptoStreamFactoryImpl( byte[] salt, int count)
     {
-        this.salt = salt;
+        this.salt = salt.clone();
         this.count = count;
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParameters.ALGORITHM;
diff --git a/src/java/org/apache/fulcrum/jce/crypto/PasswordFactory.java b/src/java/org/apache/fulcrum/jce/crypto/PasswordFactory.java
index d5d8049..1668d20 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/PasswordFactory.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/PasswordFactory.java
@@ -70,6 +70,8 @@
     
     /**
      * Factory method to get a default instance
+     * 
+     * @param algo algorithm
      * @return an instance of the CryptoStreamFactory
      */
     public synchronized static PasswordFactory getInstance(String algo) 
@@ -84,6 +86,9 @@
     
     /**
      * Factory method to get a default instance
+     * 
+     * @param algo algorithm
+     * @param count the number of MessageDigest iterations
      * @return an instance of the CryptoStreamFactory
      */
     public synchronized static PasswordFactory getInstance(String algo, int count) 
diff --git a/src/java/org/apache/fulcrum/jce/crypto/PasswordParameters.java b/src/java/org/apache/fulcrum/jce/crypto/PasswordParameters.java
index 96c66e2..2836a78 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/PasswordParameters.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/PasswordParameters.java
@@ -30,7 +30,10 @@
     /** Parameter for the number of SHA256 invocation */
     int COUNT = 1000;
 
-    /** The default password used for creating the internal password */
+    /** 
+     * The default password used for creating the internal password 
+     * @return the default password: <code>fulcrum-yaafi</code>.
+     * */
     public static char[] DefaultPassword() { 
     	return new char[] {
         (char) 'f', (char) 'u', (char) 'l', (char) 'c',
@@ -40,7 +43,9 @@
         };
     }
 
-    /** The password salt */
+    /** The password salt 
+     * @return the 8bit default salt as byte array
+     * */
     public static byte[] Salt() {
     	return new byte[] {
         (byte)0xc6, (byte)0x74, (byte)0x81, (byte)0x8a,
diff --git a/src/java/org/apache/fulcrum/jce/crypto/SmartDecryptingInputStream.java b/src/java/org/apache/fulcrum/jce/crypto/SmartDecryptingInputStream.java
index 2f188b3..58a3ce9 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/SmartDecryptingInputStream.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/SmartDecryptingInputStream.java
@@ -227,8 +227,12 @@
      */
     private boolean hasByteOrderMark( byte[] content )
     {
-        if( (content[0] == 0xFF) && (content[1] == 0xFE) || 
-        	(content[0] == 0xFE) && (content[1] == 0xFF) )
+        // bytes ar always signed in java, ff is 255
+        // removes signed parts
+        int firstUnsigned = content[0] & 0xFF;
+        int second = content[1] & 0xFF;
+        if( ((firstUnsigned == 0xFF) && (second == 0xFE)) ||
+                ((firstUnsigned == 0xFE) && (second == 0xFF)))
         {
             return true;
         }
diff --git a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
index e1f2c8e..f8bc29d 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
@@ -70,7 +70,6 @@
     public CryptoStreamGCMImpl() throws GeneralSecurityException
     {
         this.salt =  generateSalt();
-        this.count = CryptoParametersJ8.COUNT_J8;// not used
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_GCM.getAlgorithm();
     }
@@ -85,7 +84,7 @@
      */
     public CryptoStreamGCMImpl( byte[] salt, int count) 
     {
-        this.salt = salt;
+        this.salt = salt.clone();
         this.count = count;
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_GCM.getAlgorithm();
@@ -104,18 +103,21 @@
             throws GeneralSecurityException
     {
 
-        SecretKey key = new SecretKeySpec(((salt == null)? this.getSalt(): salt), "AES"); 
+        SecretKey key = new SecretKeySpec(((salt == null)? this.getSalt(): salt.clone()), "AES");
         return key;
     }
 
     /**
      * Create a Cipher.
+     * 
+     * Find additional information here: {@link GCMParameterSpec}
      *
      * @param mode the cipher mode
      * @param password the password
      * @return an instance of a cipher
      * @throws GeneralSecurityException if creating a cipher failed
      * @throws IOException creating a cipher failed
+     * 
      */
     @Override
     protected byte[] createCipher(InputStream is, int mode, char[] password )
@@ -176,7 +178,6 @@
             cipher.init( mode, key, gcmParamSpec );
 
             //algorithmParameters = cipher.getParameters();
-            
             // might update with associated Data
             // cipher.updateAAD(associatedData );// not supported PBEWithHmacSHA256AndAES_256
             
diff --git a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
index 3f418c0..12d1f15 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
@@ -23,7 +23,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.security.GeneralSecurityException;
 import java.security.Key;
@@ -32,6 +31,7 @@
 
 import javax.crypto.Cipher;
 import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.GCMParameterSpec;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.PBEParameterSpec;
@@ -68,15 +68,20 @@
 {
 
     protected static final int IV_SIZE = 16;
+    
+	/**
+	 * default count for pbe spec
+	 */
+	protected int COUNT_J8 = 10_000; // 200_000;
 
     /**
      * Constructor
-     * @throws GeneralSecurityException
+     * @throws GeneralSecurityException  if no algo could be found.
      */
     public CryptoStreamPBEImpl() throws GeneralSecurityException
     {
         this.salt =  generateSalt();
-        this.count = CryptoParametersJ8.COUNT_J8;
+        this.count = COUNT_J8;
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
     }
@@ -89,7 +94,7 @@
      */
     public CryptoStreamPBEImpl( byte[] salt, int count)
     {
-        this.salt = salt;
+        this.salt = salt.clone();
         this.count = count;
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
@@ -110,7 +115,7 @@
         SecretKeyFactory keyFactory;
         String algorithm = this.getAlgorithm();
         
-        PBEKeySpec keySpec = new PBEKeySpec(password, (salt == null)? this.getSalt(): salt, this.getCount(), KEY_SIZE );
+        PBEKeySpec keySpec = new PBEKeySpec(password, (salt == null)? this.getSalt(): salt.clone(), this.getCount(), KEY_SIZE );
 
         byte[] encodedTmp = null;
         try {
@@ -138,12 +143,15 @@
 
     /**
      * Create a Cipher.
+     * 
+     * Find additional information here: {@link PBEParameterSpec}.
      *
      * @param mode the cipher mode
      * @param password the password
      * @return an instance of a cipher
      * @throws GeneralSecurityException creating a cipher failed
      * @throws IOException creating a cipher failed
+
      */
     @Override
     protected byte[] createCipher(InputStream is, int mode, char[] password )
diff --git a/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java b/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
index 11e895e..4c7989c 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
@@ -65,7 +65,6 @@
     {
         try
         {
-
             if (args.length ==0 ){
                 printHelp();
                 return;
@@ -279,11 +278,19 @@
     public static void processString(String[] args)
         throws Exception
     {
-        String cipherMode = args[1];
-        char[] password = args[2].toCharArray();
-        String value = args[3];
+        final String cipherMode;
+        final char[] password;
+        final String value;
         File targetFile = null;
-        
+        if (args.length > 3) {
+            cipherMode = args[1];
+            password = args[2].toCharArray();
+            value = args[3];
+        } else {
+            value = null;
+            cipherMode = null;
+            password = null;
+        }
         if (args.length == 5) 
         {
             targetFile = new File(args[4]);
@@ -302,7 +309,7 @@
         
         if (value != null && !value.equals("")) 
         {
-        
+
             String result = processString(cipherMode, password, value);
             
             if (targetFile != null) {
diff --git a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
index 9cc4ba5..a02eb6a 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
@@ -28,22 +28,17 @@
 public interface CryptoParametersJ8 {
 
 	/**
-	 * default 
-	 */
-	int COUNT_J8 = 10_000; // 200_000;
-
-	/**
 	 * 
-	 * This module is using PBEWith &lt;digest&gt;And&lt;encryption&gt;:
+	 * Implementing classes are either using
 	 * 
 	 * <ul>
-	 * <li>PBEWithHmacSHA256AndAES_256/CBC/PKCS5Padding in {@link #ALGORITHM_J8_PBE}</li>
+	 * <li>PBEWith &lt;digest&gt;And&lt;encryption&gt; - the password-based encryption algorithm defined in PKCS #5: PBEWithHmacSHA256AndAES_256/CBC/PKCS5Padding in {@link #ALGORITHM_J8_PBE}</li>
 	 * </ul>
 	 * 
-	 * or Cipher Algorithm Names/Cipher Algorithm Modes/Cipher Algorithm Padding
+	 * or
 	 * 
 	 * <ul>
-	 * <li>AES/GCM/NoPadding in {@link #ALGORITHM_J8_GCM}</li>
+	 * <li>AES/GCM/NoPadding in {@link #ALGORITHM_J8_GCM} (Cipher Algorithm Names/Cipher Algorithm Modes/Cipher Algorithm Padding). Cipher is Galois/Counter Mode, as defined in NIST Special Publication SP 800-38D: </li>
 	 * </ul>
 	 * 
 	 * 
@@ -51,12 +46,17 @@
 	 * 
 	 * Algo/mode/padding for cipher transformation:
 	 * 
-	 * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">The Oracle Security Standard Names Cipher Algorithms</a>
+	 * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">Java 8: The Oracle Security Standard Names Cipher Algorithms</a>
+	 * 
+	 * @see <a href="https://docs.oracle.com/en/java/javase/14/docs/specs/security/standard-names.html#security-algorithm-implementation-requirements">Java 14: Security Algorithm Implementation Requirements</a>
+	 * 
+	 * 
 	 */
 	public enum TYPES_IMPL {
 		
+		// key size 256
 		ALGORITHM_J8_PBE("PBEWithHmacSHA256AndAES_256"), 
-		
+		// key size 128
 		ALGORITHM_J8_GCM("AES/GCM/NoPadding");
 
 		private final String algorithm;
diff --git a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
index 724afaf..dbd5fb3 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
@@ -72,7 +72,7 @@
     /** the default instances */
     protected static Map<TYPES,CryptoStreamFactoryJ8Template> instances = new ConcurrentHashMap<>();
     
-    protected AlgorithmParameters algorithmParameters;// used only for debugging
+    //protected AlgorithmParameters algorithmParameters;// used only for debugging
    
     public CryptoStreamFactoryJ8Template() {
        
@@ -114,7 +114,7 @@
      */
     public CryptoStreamFactoryJ8Template( byte[] salt, int count, TYPES type)
     {
-        this.salt = salt;
+        this.salt = salt.clone();
         this.count = count;
         this.providerName = PROVIDERNAME;
         this.algorithm = type.equals(TYPES.PBE)? CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm():
@@ -141,14 +141,14 @@
     public InputStream getInputStream( InputStream is, char[] password )
         throws GeneralSecurityException, IOException
     {
-        byte[] decrypted =  this.createCipher( is, Cipher.DECRYPT_MODE, password );
+        byte[] decrypted =  this.createCipher( is, Cipher.DECRYPT_MODE, password.clone() );
         InputStream eis = new ByteArrayInputStream(decrypted);
         return eis;
     }
 
     public OutputStream getOutputStream(InputStream is, OutputStream os, char[] password)
             throws GeneralSecurityException, IOException {
-        byte[] encrypted =  this.createCipher( is, Cipher.ENCRYPT_MODE, password );
+        byte[] encrypted =  this.createCipher( is, Cipher.ENCRYPT_MODE, password.clone() );
         InputStream eis = new ByteArrayInputStream(encrypted);
         StreamUtil.copy(eis, os);
         return os;
@@ -257,11 +257,11 @@
     }
 
 	public byte[] getSalt() {
-		return salt;
+		return salt.clone();
 	}
 
 	public void setSalt(byte[] salt) {
-		this.salt = salt;
+		this.salt = salt.clone();
 	}
 
 	public int getCount() {
diff --git a/src/test/org/apache/fulcrum/jce/crypto/extended/Main8Test.java b/src/test/org/apache/fulcrum/jce/crypto/extended/Main8Test.java
index 28f40b4..6453529 100644
--- a/src/test/org/apache/fulcrum/jce/crypto/extended/Main8Test.java
+++ b/src/test/org/apache/fulcrum/jce/crypto/extended/Main8Test.java
@@ -192,7 +192,8 @@
             conf.put("enc",TYPES.GCM);
 
             // encode as string to stderr and  file in hexdecimal format
-            String[] encryptionArgs = { "string", "enc"+ conf.get("enc"), this.password, 
+            String[] encryptionArgs = {
+                    "string", "enc"+ conf.get("enc"), this.password,
                     topSecret, 
                     "./target/main8/integrated-plain16chars.enc.txt"};
             CLI2.main(encryptionArgs);
diff --git a/xdocs/examples.xml b/xdocs/examples.xml
index cc1265a..5dd4c01 100644
--- a/xdocs/examples.xml
+++ b/xdocs/examples.xml
@@ -17,7 +17,6 @@
  specific language governing permissions and limitations

  under the License.

 -->

-

 <document>

 

   <properties>

@@ -34,13 +33,24 @@
  java -classpath target/classes org.apache.fulcrum.jce.crypto.cli.CLI2 string enc changeit mysecretgeheim  

  ]]>

                 </source>

-                    </p>

-     </subsection>

+         </p>

+          <p>An example using an ant build tool and property file is the provided Integration Test in pom.xml.

+          By default running this will write the encrypted password to src/filters/filter-integration-test.properties and the decrypted password to target/integration-test/filtered-pw.properties.  On the command line with custom password and meta password this is done like this (assuming -Dskip.pw.gen=false  -Dskip.pw.encrypt=false):

+                <source> 

+                <![CDATA[

+mvn integration-test  -Dtest.password="xyz" -Dmeta.pw="abc"  

+ ]]>

+                </source>

+         </p>

+         

+         

+            </subsection>

      <subsection name="Code Usage">

-               <p>

-                    <source>

+       <p>

+          <source>

 <![CDATA[

-    // provide  target_password, meta_password        

+    // provide target_password, meta_password

+            

     char[] password = meta_password.toCharArray();

     // default

     CryptoUtilJ8 cryptoUtilJ8 = CryptoUtilJ8.getInstance();

@@ -63,17 +73,19 @@
         ...

     }

   ]]>

-                    </source>

-                   </p>

+              </source>

+           </p>

       </subsection> 

-      </section>

-      <section name="Building a Project">

+   </section>

+   <section name="Building a Project">

       <subsection name="Prepare the crypto-tool with Maven Assembly">

-            <p>First we build our crypto tool as executable jar in phase initialize (i.e. very early, to use it later) and name it <i>crypto-tool</i> using the assembly description saved in the file <i>build/assembly.xml</i> described below. Add this into your project pom.xml file.

-                <source>

+         <p>First we build our crypto tool as executable jar in phase initialize (i.e. very early, to use it later) and name it <i>crypto-tool</i> 

+            using the assembly description saved in the file <i>build/assembly.xml</i> described below. 

+            Add this into your project pom.xml file.

+            <source>

                 <![CDATA[

 <plugin>

-      <artifactId>maven-assembly-plugin</artifactId>

+    <artifactId>maven-assembly-plugin</artifactId>

     <version>3.3.0</version>

     <configuration>

        <finalName>crypto-tool</finalName>  

@@ -94,14 +106,16 @@
     <goals>

       <goal>single</goal>

     </goals>

-  </execution>

-</executions>

+   </execution>

+  </executions>

 </plugin>

                 ]]>

-                </source>

-               </p>

-               <p>Using this assembly description (adapted to our needs from the descriptor-ref jar-with-dependencies) the executable jar will be generated in target folder and will just include fulcrum yaafi-crypto classes. Here you will get a very tiny jar (build with java 8 on windows less than 45kb), as the tool has no library dependencies!

-                <source>

+      </source>

+   </p>

+   <p>Using this assembly description (adapted to our needs from the descriptor-ref jar-with-dependencies) the executable jar will be generated 

+       in target folder and will just include fulcrum yaafi-crypto classes. 

+       Here you will get a very tiny jar (build with java 8 on windows less than 45kb), as the tool has no library dependencies!

+      <source>

                 <![CDATA[

 <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

@@ -124,32 +138,43 @@
   </dependencySets>

 </assembly>

                 ]]>

-                </source>

-            </p>

-              <p>After executing the following command the <i>crypto tool</i> is available in your project and we could use it to generate an encrypted password using a master password (to be saved separately and not in the project). This is done in the step.

-                <source>

-                <![CDATA[

+     </source>

+ </p>

+ <p>After executing the following command the <i>crypto tool</i> is available in your project and 

+   we could use it to generate an encrypted password using a master password (to be saved separately and not in the project). 

+   This is done in the following step.

+   <source>

+            <![CDATA[

  mvn initialize

-                ]]>

-                </source>

-                    </p>

-    </subsection>

-      <subsection name="Integrate with Ant Tool">

-      <p>First we encrypt the password using our master password and after that copying and save the encrypted password in one of our project's configuration files.  Running the following command will show the encrypted password. Save the encrypted password as value with key  key <i>password_encrypted</i> in an existing source property file, i.e. a configuration file of your project, which will be used later.

-            <source>

+               ]]>

+    </source>

+    </p>

+  </subsection>

+  <subsection name="Integrate with Ant Tool - Extended">

+    <p>Check the pom.xml's integration test ant calls. The following is an extended version using its own assembly, but is very similar to the integration test.</p>

+    <p>First we <i>encrypt</i> the password on the command line using our master password and after that we copy and save the encrypted password in one of our project's configuration files. 

+      Running the following command will show the encrypted password.

+      <source>

             <![CDATA[  

- java -jar target\crypto-tool.jar  string enc <master.pw> <unencrypted.password>

+ java -jar target/crypto-tool.jar string enc <master.pw> <unencrypted.password>

  ]]>

-            </source>

-                </p>

-         <p>Use the following xml code and save it into <i>build/build-pw.xml</i>. This is the ant build file we use to <i>decrypt</i> the encrypted password and use it while building the project. The example is configured as follows:

-         The global master password is set as environment variable "<i>meta.pw</i>". The already encrypted password is expected to be set in a source property file <i>source.property.path</i> (i.e. configuration file of your project) as value in key <i>password_encrypted</i> .  It will be read in automatically as ant variable ${password_encrypted}. The <i>decrypted</i> password will be saved to key "<i>password</i>" in another property file (<i>target.property.path</i>), which should not be set into version control. You may need to create it new.

-         You may use the ant tool as is setting the variables in <i>.build.properties</i> or integrate it in your pom.xml build process (see below).

-                <source>

-                <![CDATA[  

+       </source>

+       Save the encrypted password as value with key <i>password_encrypted</i> 

+      in an existing configuration file of your project, which will be used later. 

+      You may include this process into your build tool (by invoking target init) similar as we do it for the <i>decrypting</i> process (see below paragraph).      

+   </p>

+   <p>Use the following ant build script (windows only) and save it into <i>build/build-pw.xml</i>. This is the ant build file we use to <i>decrypt</i> the encrypted password and 

+      use it while building the project. The example is configured as follows:

+      The global master password is set as environment variable "<i>meta.pw</i>". The already encrypted password is expected to be set in a source property file <i>source.property.path</i> 

+      (i.e. configuration file of your project) as value in key <i>password_encrypted</i> .  It will be read in automatically as ant variable ${password_encrypted}. 

+      The <i>decrypted</i> password will be saved to key "<i>password</i>" in another property file (<i>target.property.path</i>), which should not be set into version control. You may need to create it new.

+      You may use the ant tool as is setting the variables in <i>.build.properties</i> or integrate it in your pom.xml build process (see below).

+       <source>

+   <![CDATA[  

 <project basedir="."  default="build" name="build">

   <property environment="env"/>

    <property file=".build.properties"/>  

+   <!-- reading from the file properties: password_encrypted, password -->

    <property file="${source.property.path}"/>

    <property name="meta.pw" value="${env.meta.pw}"/>

 

@@ -160,6 +185,7 @@
          <arg value="java -version"/>

       </exec>

     </target>

+    

    <target name="decrypt">

       <echo message="executing java -jar target/${jarname}.jar string dec ${meta.pw} ${password_encrypted}."/>

       <exec executable="cmd" dir="${build.path}/../" osfamily="windows" resultproperty="success" outputproperty="decoded.pw">

@@ -167,8 +193,37 @@
          <arg value="java -jar target/${jarname}.jar string dec ${meta.pw} ${password_encrypted}"/>

       </exec>

     </target>

+      

+   <target name="update">

+       <echo message="updating password in properties file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password" value="${decoded.pw}"/>

+        </propertyfile>

+    </target>

     

-    <target name="run">

+   <target name="encrypt">

+      <echo message="executing java -jar target/${jarname}.jar string enc ${meta.pw} ${password}"/>

+      <exec executable="cmd" dir="${build.path}/../" osfamily="windows" resultproperty="success" outputproperty="encoded.pw">

+        <arg value="/c"/>

+         <arg value="java -jar target/${jarname}.jar string enc ${meta.pw} ${password}"/>

+      </exec>

+    </target>

+    

+  <target name="init-update">

+       <echo message="updating password_encrypted in properties file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password_encrypted" value="${encoded.pw}"/>

+        </propertyfile>

+    </target>

+  

+  <target name="clean">

+   <echo message="cleaning up key password in propert file: ${target.property.path}."/>

+       <propertyfile file="${target.property.path}" >

+          <entry  key="password" value=""/>

+        </propertyfile>

+  </target>

+

+  <!-- target name="run">

         <echo message="test output java -jar target/${jarname}.jar string dec ${meta.pw} ${password_encrypted}."/>

         <java jar="./../target/${jarname}.jar" fork="true">

         <arg value="string"/>

@@ -176,34 +231,26 @@
         <arg value="${meta_password}"/>

         <arg value="${password_encrypted}"/>

         </java>

-    </target>

+  </target-->

   

-   <target name="update">

-   <echo message="updating propert file: ${target.property.path}."/>

-       <propertyfile file="${target.property.path}" >

-          <entry  key="password" value="${decoded.pw}"/>

-        </propertyfile>

-  </target>

-  

-<target name="clean">

-   <echo message="cleaning up key password in propert file: ${target.property.path}."/>

-       <propertyfile file="${target.property.path}" >

-          <entry  key="password" value=""/>

-        </propertyfile>

-  </target>

-  

+  <!-- decrypt to password -->

    <target name="build" depends="testjava, decrypt, update">

   </target>

   

- </project>    

-                    

+  <!-- encrypt to password_encrypted -->

+    <target name="init" depends="testjava, encrypt, init-update">

+  </target>

+  

+ </project>      

                 ]]>

-                </source>

-         </p>

-       </subsection>

-      <subsection name="Integration ANT Task into Maven Life cycle">

-    <p>Integrate the ant tool, check the file name and run maven command below after setting your configuration or filter files in <i>source.property.path</i> and <i>target.property.path</i>. You may add another clean-up in a later life cycle phase, e.g. post-integration-test. You may also simplify the process by cleaning always and using the same source and target property file.

-            <source>

+         </source>

+     </p>

+  </subsection>

+  <subsection name="Integration ANT Task into Maven Life cycle">

+    <p>Integrate the ant tool, check the file name and run maven command below after setting your configuration or filter files in <i>source.property.path</i> and <i>target.property.path</i>. 

+    You may add another clean-up in a later life cycle phase, e.g. post-integration-test. 

+    You may also simplify the process by cleaning always and using the same source and target property file.

+      <source>

             <![CDATA[

 <plugin>

    <artifactId>maven-antrun-plugin</artifactId>

@@ -249,14 +296,15 @@
     </executions>

   </plugin>

             ]]>

-            </source>

-                </p>

-       </subsection>

-          <subsection name="Maven Command line examples">

-              <p>Save the decrypted password for the build

-                <source>

+       </source>

+   You may add another  execution definiton with id and target "init" and probably another skip property to initially or regularily update the encoded password.

+     </p>

+  </subsection>

+  <subsection name="Maven Command line examples">

+     <p>Save the decrypted password for the build

+         <source>

                 <![CDATA[

-mvn  clean test -Dmeta.pw=<securepwd>

+mvn clean test -Dmeta.pw=<securepwd>

                 ]]>

                 </source>

                     </p>

@@ -267,20 +315,20 @@
                 ]]>

                 </source>

                     </p>

-                        <p>Clean up finally.

+ <p>Clean up finally.

                 <source>

                 <![CDATA[

 mvn clean 

-                ]]>

-                </source>

-                    </p>

-                    <p>This example could be extended or adapted, eg. by using multiple passwords, or encrypting an entire file. 

-                    Have fun!

-                    </p><p>

-                    TODO Show gradle example..

-                    </p>

-     </subsection>

-    </section>

+               ]]>

+        </source>

+    </p>

+    <p>This example could be extended or adapted, eg. by using multiple passwords, or encrypting an entire file. 

+       Have fun!

+    </p>

+    <p>TODO Show gradle example..

+      </p>

+    </subsection>

+   </section>

 

   </body>

 

diff --git a/xdocs/index.xml b/xdocs/index.xml
index 9397ade..66a9b0d 100644
--- a/xdocs/index.xml
+++ b/xdocs/index.xml
@@ -29,7 +29,7 @@
 
     <section name="Overview">
       <p> Fulcrum YAFFI Crypto Library is an extension library for Fulcrum YAAFI to support
-        transparent decryption of configuration files. The encryption/decryption is based by default on <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html" target="blank_">PBEWithHmacSHA256AndAES_256</a> (PBEWith&lt;digest&gt;And&lt;encryption&gt;algorithm.)  with 128bit key length.</p>
+        transparent decryption of configuration files. The encryption/decryption is based by default on <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html" target="blank_">PBEWith&lt;digest&gt;And&lt;encryption&gt;</a> algorithm (PBEWithHmacSHA256AndAES_256) with 128bit key length.</p>
     </section>
 
     <section name="Functionality">
@@ -41,7 +41,7 @@
       </p>
       <subsection name="Password Creation">
         <p> Why someone need a password factory to create safer password?! People tend to use weak
-          password vunerable to dictionary attacks. To improve the situation you have a base
+          password vulnerable to dictionary attacks. To improve the situation you have a base
           password which you convert into the real password using the PasswordFactory. For the
           password generation the base password is salted and repeatedly hashed to generate a UUID
           string (which you can still manually enter on the keyboard). Furthermore the password
@@ -106,12 +106,18 @@
             Java Cryptography Architecture Oracle Providers Documentation for Java Platform Standard Edition 7</a>
             </td>
           </tr>
-           <tr>
+          <tr>
             <td>JDK 1.8.x</td>
             <td> <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html">
             Java Cryptography Architecture Oracle Providers Documentation for JDK 8</a>
             </td>
           </tr>
+           <tr>
+            <td>JDK 14</td>
+            <td> <a href="https://docs.oracle.com/en/java/javase/14/security/java-cryptography-architecture-jca-reference-guide.html">
+            Java Cryptography Architecture Oracle Providers Documentation for JDK 14</a>
+            </td>
+          </tr>
         </table>
       </subsection>
       <subsection name="Availabe Algorithms">