- removed duplicate method in CryptoParametersJ8 and (almost) duplicate class CryptoStreamFactoryJ8Impl (as in CryptoStreamPBEImpl)
- cleanup java code
- remove hard coded SH1PRNG, replacing it with SecureRandom.getInstanceStrong in CryptoStreamFactoryJ8Template
- fixing javadoc, xdoc
- updating to testcontainer 9-SNAPSHOT (fixing eclipse ide integration issue)
- update svn:ignore prop



git-svn-id: https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/yaafi-crypto@1879399 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/NOTICE.txt b/NOTICE.txt
index 838338d..de693dd 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Turbine Fulcrum YAAFI-Cypto Component
-Copyright 2002-2019 The Apache Software Foundation.
+Copyright 2002-2020 The Apache Software Foundation.
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/pom.xml b/pom.xml
index 061fc8e..bef15db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,7 +74,7 @@
       <!-- to gt junit 5 -->
       <groupId>org.apache.fulcrum</groupId>
       <artifactId>fulcrum-testcontainer</artifactId>
-      <version>1.0.8</version>
+      <version>1.0.9-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
     <dependency>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1e5046b..5c970f3 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -25,8 +25,8 @@
 
   <body>
     <release version="1.0.8" date="as in SVN">
-      <action dev="jk" type="update">
-        Add Java 8 PBEWithHmacSHA256AndAES_128 based encryption
+      <action dev="gk" type="update">
+        Added two Java 8 implementations based on PBE (PBEWithHmacSHA256AndAES_128) 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/java/org/apache/fulcrum/jce/crypto/CryptoParameters.java b/src/java/org/apache/fulcrum/jce/crypto/CryptoParameters.java
index 947e591..914f020 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/CryptoParameters.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/CryptoParameters.java
@@ -31,7 +31,12 @@
     /** Parameter for PBEParameterSpec */
     int COUNT = 20;
 
-    /** The password salt: update to a method to prevent malicious code bug */
+    /** 
+     * The password salt: update to a method to prevent malicious code bug.
+     * 
+     * @return the salt 
+     * 
+     * */
     public static byte[] Salt() 
     {
     	return new byte[] 
@@ -42,7 +47,6 @@
     }
     
     
-    /** The crypto algorithm being used */
-    String ALGORITHM = "PBEWithMD5AndDES";
-    
-}
+    /** 
+     * The default crypto algorithm being used */
+    String ALGORITHM = "PBEWithMD5AndDES";}
diff --git a/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java b/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
index 6c491dc..8f7de9d 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
@@ -125,6 +125,8 @@
 
     /**
      * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getSmartInputStream(java.io.InputStream,char[])
+     * 
+     * 
      */
     public InputStream getSmartInputStream(InputStream is, char[] password )
         throws GeneralSecurityException, IOException
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 dde400c..e1f2c8e 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
@@ -37,6 +37,7 @@
 import org.apache.fulcrum.jce.crypto.StreamUtil;
 import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8;
 import org.apache.fulcrum.jce.crypto.extended.CryptoStreamFactoryJ8Template;
+import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8.TYPES;
 
 /**
  * Concrete implementation for creating encrypting/decrypting streams. The
@@ -53,14 +54,18 @@
  *
  *
  * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
+ * 
+ * The Implementation for {@link TYPES} GCM.
  */
 
 public final class CryptoStreamGCMImpl extends CryptoStreamFactoryJ8Template
 {  
 
     protected static final int IV_SIZE = 12;
+    
     /**
      * Constructor
+     * @throws GeneralSecurityException  - wraps {@link NoSuchAlgorithmException}
      */
     public CryptoStreamGCMImpl() throws GeneralSecurityException
     {
@@ -76,8 +81,9 @@
      *
      * @param salt the salt for the PBE algorithm
      * @param count the iteration for PBEParameterSpec
+
      */
-    public CryptoStreamGCMImpl( byte[] salt, int count) throws GeneralSecurityException
+    public CryptoStreamGCMImpl( byte[] salt, int count) 
     {
         this.salt = salt;
         this.count = count;
@@ -91,7 +97,7 @@
      * @param password the password to use.
      * @param salt if provided this is used, otherweise {@link #getSalt()}.
      * @return the key
-     * @throws GeneralSecurityException creating the key failed
+     * @throws GeneralSecurityException if creating the key failed
      */
     @Override
     protected Key createKey( char[] password, byte[] salt ) 
@@ -108,7 +114,7 @@
      * @param mode the cipher mode
      * @param password the password
      * @return an instance of a cipher
-     * @throws GeneralSecurityException creating a cipher failed
+     * @throws GeneralSecurityException if creating a cipher failed
      * @throws IOException creating a cipher failed
      */
     @Override
@@ -190,6 +196,11 @@
         return ciphertext;
     }
     
+    /**
+     * 
+     * @return the random byte array from {@link SecureRandom} SHA1PRNG (as default)
+     * @throws GeneralSecurityException - if creating the key failed
+     */
     private byte[] generateIV( ) throws GeneralSecurityException {
         SecureRandom random;
         try {
@@ -202,10 +213,6 @@
         }
     }
 
-    @Override
-    protected Cipher createCipher(int encryptMode, char[] password) throws GeneralSecurityException, IOException {
-        throw new RuntimeException("not provided for this implementation");
-    }
 
 
 }
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 bc2d54a..3f418c0 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
@@ -23,6 +23,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.security.GeneralSecurityException;
 import java.security.Key;
@@ -37,6 +38,7 @@
 
 import org.apache.fulcrum.jce.crypto.StreamUtil;
 import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8;
+import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8.TYPES;
 import org.apache.fulcrum.jce.crypto.extended.CryptoStreamFactoryJ8Template;
 
 /**
@@ -44,7 +46,7 @@
  * implementation uses the JCA (Java Crypto Extension) supplied
  * by SUN (using SunJCE 1.42).
  *
- * The implementation uses as @see {@link CryptoParametersJ8#ALGORITHM_J8_PBE} for encryption which
+ * The implementation uses as @see {@link CryptoParametersJ8} ALGORITHM_J8_PBE for encryption which
  * should be sufficient for most applications.
  *
  * The implementation also supplies a default password in the case that
@@ -58,14 +60,18 @@
  * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
  * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
  * @author <a href="mailto:maakus@earthlink.net">Markus Hahn</a>
+ * 
+ * The Implementation for {@link TYPES} PBE.
  */
 
 public final class CryptoStreamPBEImpl extends CryptoStreamFactoryJ8Template
 {
 
     protected static final int IV_SIZE = 16;
+
     /**
      * Constructor
+     * @throws GeneralSecurityException
      */
     public CryptoStreamPBEImpl() throws GeneralSecurityException
     {
@@ -81,7 +87,7 @@
      * @param salt the salt for the PBE algorithm
      * @param count the iteration for PBEParameterSpec
      */
-    public CryptoStreamPBEImpl( byte[] salt, int count) throws GeneralSecurityException
+    public CryptoStreamPBEImpl( byte[] salt, int count)
     {
         this.salt = salt;
         this.count = count;
@@ -95,7 +101,7 @@
      * @param password the password to use.
      * @param salt if provided this is used, otherweise {@link #getSalt()}.
      * @return the key
-     * @throws GeneralSecurityException creating the key failed
+     * @throws GeneralSecurityException if creating the key failed
      */
     @Override
     protected Key createKey( char[] password, byte[] salt ) 
@@ -108,7 +114,7 @@
 
         byte[] encodedTmp = null;
         try {
-            if( getProviderName() == null )
+            if( this.getProviderName() == null )
             {
                 keyFactory = SecretKeyFactory.getInstance( algorithm );
             }
@@ -212,10 +218,4 @@
         return ciphertext;
     }
 
-
-    @Override
-    protected Cipher createCipher(int encryptMode, char[] password) throws GeneralSecurityException, IOException {
-        throw new RuntimeException("not provided for this implementation");
-    }
-
 }
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 b00fbd8..11e895e 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
@@ -46,10 +46,10 @@
  * 
  * Example :
  * 
- * java -classpath target/classes org.apache.fulcrum.jce.crypto.cli.CLI2 string enc changeit mysecretgeheim
+ * <pre>java -classpath target/classes org.apache.fulcrum.jce.crypto.cli.CLI2 string enc changeit mysecretgeheim</pre>
  * ...
  * 
- * java -cp target/classes org.apache.fulcrum.jce.crypto.cli.Main string dec changeit J8_AES256;<hashcode>
+ * <pre>java -cp target/classes org.apache.fulcrum.jce.crypto.cli.Main string dec changeit J8_AES256 </pre>
  *
  * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
  */
@@ -324,6 +324,8 @@
      * @param password as char array
      * @param value String to be en/decrypted
      * @throws Exception the operation failed
+     * 
+     * @return the result - either the encrypted or decrypted string depending on cipherMode
      */
     public static String processString(String cipherMode, char[] password, String value)
         throws Exception
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 f70fa32..9cc4ba5 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
@@ -19,70 +19,70 @@
  * under the License.
  */
 
-
 /**
  * CryptoParameters used for encryption/decryption.
  *
  * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
  */
 
-public interface CryptoParametersJ8
-{
+public interface CryptoParametersJ8 {
 
-    int COUNT_J8 = 10_000; //200_000;
-    
-    /**
-     *  @see https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJCEProvider
-     *  
-     *  Algo/mode/padding for cipher transformation: 
-     *  @see https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
-     *  
-     *  using PBEWith &lt;digest&gt;And&lt;encryption&gt;: 
-     *  
-     *  <ul>
-     *  <li>PBEWithHmacSHA256AndAES_256/CBC/PKCS5Padding</li>
-     *  </ul>
-     *  
-     *  or
-     *  Cipher Algorithm Names/Cipher Algorithm Modes/Cipher Algorithm Padding
-     *  
-     *  <ul>
-     *  <li>AES/GCM/NoPadding</li>
-     *  </ul> 
-     */
-    
-    public enum TYPES_IMPL 
-    {
-        ALGORITHM_J8_PBE("PBEWithHmacSHA256AndAES_256"), 
-        ALGORITHM_J8_GCM("AES/GCM/NoPadding");
-        
-        private final String algorithm;
-        
-        private TYPES_IMPL(String algo) 
-        {
-            algorithm = algo;
-        }
-        
-        @Override
-        public String toString() 
-        {
-            return this.algorithm;
-        }
-        
-        public String getAlgorithm() 
-        {
-            return algorithm;
-        }
-    }
-    
-    public enum TYPES {
-        PBE, GCM
-    }
-    
-    /**
-     * Prefix to decrypted hex hash to get a clue, what to use and what it is.
-     * 
-     * This should be always 10 bytes
-     */
-    String CLEAR_CODE_J8 = "J8_AES256;";
+	/**
+	 * default 
+	 */
+	int COUNT_J8 = 10_000; // 200_000;
+
+	/**
+	 * 
+	 * This module is using PBEWith &lt;digest&gt;And&lt;encryption&gt;:
+	 * 
+	 * <ul>
+	 * <li>PBEWithHmacSHA256AndAES_256/CBC/PKCS5Padding in {@link #ALGORITHM_J8_PBE}</li>
+	 * </ul>
+	 * 
+	 * or Cipher Algorithm Names/Cipher Algorithm Modes/Cipher Algorithm Padding
+	 * 
+	 * <ul>
+	 * <li>AES/GCM/NoPadding in {@link #ALGORITHM_J8_GCM}</li>
+	 * </ul>
+	 * 
+	 * 
+	 * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJCEProvider">The Oracle Security SunJCE Provider</a>
+	 * 
+	 * 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>
+	 */
+	public enum TYPES_IMPL {
+		
+		ALGORITHM_J8_PBE("PBEWithHmacSHA256AndAES_256"), 
+		
+		ALGORITHM_J8_GCM("AES/GCM/NoPadding");
+
+		private final String algorithm;
+
+		private TYPES_IMPL(String algo) {
+			algorithm = algo;
+		}
+
+		@Override
+		public String toString() {
+			return this.algorithm;
+		}
+
+		public String getAlgorithm() {
+			return algorithm;
+		}
+	}
+
+	public enum TYPES {
+		PBE, GCM
+	}
+
+	/**
+	 * Prefix to decrypted hex hash to get a clue, what to use and what it is.
+	 * 
+	 * This should be always 10 bytes
+	 */
+	String CLEAR_CODE_J8 = "J8_AES256;";
 }
diff --git a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8.java b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8.java
index c0cde9f..3d73493 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8.java
@@ -47,16 +47,4 @@
     OutputStream getOutputStream(InputStream is, OutputStream os, char[] password)
         throws GeneralSecurityException, IOException;
     
-    /**
-     * Creates input stream based on the decryption mode
-     * using the default password.
-     *
-     * @param is the input stream to be wrapped
-     * @param decryptionMode the decryption mode (true|false|auto)
-     * @return an decrypting input stream
-     * @throws GeneralSecurityException creating the input stream failed
-     * @throws IOException creating the input stream failed
-     */
-    InputStream getInputStream(InputStream is, char[] password)
-            throws GeneralSecurityException, IOException;
 }
diff --git a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Impl.java b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Impl.java
deleted file mode 100644
index 3c45bc0..0000000
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Impl.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package org.apache.fulcrum.jce.crypto.extended;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- *  * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.PBEParameterSpec;
-
-import org.apache.fulcrum.jce.crypto.CryptoStreamFactoryImpl;
-import org.apache.fulcrum.jce.crypto.PasswordFactory;
-import org.apache.fulcrum.jce.crypto.StreamUtil;
-
-/**
- * Concrete factory for creating encrypting/decrypting streams. The
- * implementation uses the JCA (Java Crypto Extension) supplied
- * by SUN (using SunJCE 1.42).
- *
- * The implementation uses as PBEWithHmacSHA256AndAES_256, see {@link CryptoParametersJ8#ALGORITHM_J8} for encryption which
- * should be sufficent for most applications.
- *
- * The implementation also supplies a default password in the case that
- * the programmer don't want to have additional hassles. It is easy to
- * reengineer the password being used but much better than a hard-coded
- * password in the application.
- *
- * The code uses parts from Markus Hahn's Blowfish library found at
- * http://blowfishj.sourceforge.net/
- *
- * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
- * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
- * @author <a href="mailto:maakus@earthlink.net">Markus Hahn</a>
- */
-@Deprecated
-public final class CryptoStreamFactoryJ8Impl extends CryptoStreamFactoryImpl implements CryptoStreamFactoryJ8
-{
-
-    private static final int SALT_SIZE = 128; //might increase cipher length
-    private static final int KEY_SIZE = 256;
-
-    /** the default instance */
-    private static CryptoStreamFactoryJ8 instance;
-    
-    /**
-     * Factory method to get a default instance
-     * @return an instance of the CryptoStreamFactory
-     */
-    public synchronized static CryptoStreamFactoryJ8 getInstance() 
-    {
-        if( CryptoStreamFactoryJ8Impl.instance == null )
-        {
-            try {
-                CryptoStreamFactoryJ8Impl.instance = new CryptoStreamFactoryJ8Impl();
-            } catch (GeneralSecurityException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        return CryptoStreamFactoryJ8Impl.instance;
-    }
-
-    /**
-     * Set the default instance from an external application.
-     * @param instance the new default instance
-     */
-    public static void setInstance( CryptoStreamFactoryJ8 instance )
-    {
-        CryptoStreamFactoryJ8Impl.instance = instance;
-    }
-
-    /**
-     * Constructor
-     */
-    public CryptoStreamFactoryJ8Impl() throws GeneralSecurityException
-    {
-        this.salt =  generateSalt();
-        this.count = CryptoParametersJ8.COUNT_J8;
-        this.providerName = PROVIDERNAME;
-        this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
-    }
-    
-    /**
-     * Constructor
-     */
-    public CryptoStreamFactoryJ8Impl(String algo) throws GeneralSecurityException
-    {
-        this.salt =  generateSalt();
-        this.count = CryptoParametersJ8.COUNT_J8;
-        this.providerName = PROVIDERNAME;
-        this.algorithm = algo;
-    }
-
-    /**
-     * Constructor
-     *
-     * @param salt the salt for the PBE algorithm
-     * @param count the iteration for PBEParameterSpec
-     */
-    public CryptoStreamFactoryJ8Impl( byte[] salt, int count)
-    {
-        this.salt = salt;
-        this.count = count;
-        this.providerName = PROVIDERNAME;
-        this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
-    }
-
-
-    /**
-     * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getSmartInputStream(java.io.InputStream)
-     */
-    @Override
-    public InputStream getSmartInputStream(InputStream is)
-        throws GeneralSecurityException, IOException
-    {
-        return this.getSmartInputStream(
-            is,
-            PasswordFactory.getInstance("SHA-256").create()
-            );
-    }
-
-    /**
-     * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getInputStream(java.io.InputStream,char[])
-     */
-    @Override
-    public InputStream getInputStream( InputStream is, char[] password )
-        throws GeneralSecurityException, IOException
-    {
-        byte[] encrypted =  this.createCipher( is, Cipher.DECRYPT_MODE, password );
-        InputStream eis = new ByteArrayInputStream(encrypted);
-        return eis;
-    }
-
-    
-    @Override
-    public OutputStream getOutputStream(InputStream is, OutputStream os, char[] password)
-            throws GeneralSecurityException, IOException {
-        byte[] encrypted =  this.createCipher( is, Cipher.ENCRYPT_MODE, password );
-        InputStream eis = new ByteArrayInputStream(encrypted);
-        StreamUtil.copy(eis, os);
-        return os;
-    }
-
-    /**
-     * Create a PBE key.
-     *
-     * @param password the password to use.
-     * @param salt if provided this is used, otherweise {@link #getSalt()}.
-     * @return the key
-     * @throws GeneralSecurityException creating the key failed
-     */
-    private Key createKey( char[] password, byte[] salt ) 
-            throws GeneralSecurityException
-    {
-        SecretKeyFactory keyFactory;
-        String algorithm = this.getAlgorithm();
-        
-        PBEKeySpec keySpec = new PBEKeySpec(password, (salt == null)? this.getSalt(): salt, this.getCount(), KEY_SIZE );
-        byte[] encodedTmp = null;
-        try {
-            if( this.getProviderName() == null )
-            {
-                keyFactory = SecretKeyFactory.getInstance( algorithm );
-            }
-            else
-            {
-                keyFactory = SecretKeyFactory.getInstance( algorithm, this.getProviderName() );
-            }
-            return keyFactory.generateSecret(keySpec);
-            
-        } catch (NoSuchAlgorithmException e) {
-            throw new GeneralSecurityException(e);
-        } finally {
-            if (encodedTmp != null) {
-                Arrays.fill(encodedTmp, (byte)0); 
-            }
-            if (keySpec != null) {
-                keySpec.clearPassword();
-            }
-        }
-    }
-
-    /**
-     * Create a Cipher.
-     *
-     * @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
-     */
-    private byte[] createCipher(InputStream is, int mode, char[] password )
-        throws GeneralSecurityException, IOException
-    {
-        Cipher cipher;
-        PBEParameterSpec paramSpec = null; 
-        
-        ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
-        StreamUtil.copy(is, bos);
-        
-        byte[] input = bos.toByteArray();
-        byte[] ciphertext = null;
-        byte[] salt = null;
-        byte[] iv = null;
-        if (mode == Cipher.DECRYPT_MODE) 
-        {     
-            salt = Arrays.copyOfRange(input, 0, SALT_SIZE / 8);
-            iv = Arrays.copyOfRange(input, salt.length, salt.length + 128 / 8);
-            ciphertext = Arrays.copyOfRange(input, salt.length + iv.length, input.length);// cut out salt and iv
-        }
-        
-        Key key = this.createKey( password, salt );
-        
-        if( this.getProviderName() == null )
-        {
-            cipher = Cipher.getInstance( this.getAlgorithm() );
-        }
-        else
-        {
-            cipher = Cipher.getInstance( this.getAlgorithm(), this.getProviderName() );
-        }
-        
-        // save
-        if (mode == Cipher.DECRYPT_MODE) {
-            paramSpec = new PBEParameterSpec( salt, this.getCount(), new IvParameterSpec(iv) );
-            cipher.init( mode, key, paramSpec );
-            //cipher.init( mode, key, algorithmParameters );
-            ciphertext = cipher.doFinal(ciphertext); // actually the unencrypted bytes
-        }
-        
-        // save
-        if (mode == Cipher.ENCRYPT_MODE) {        
-            paramSpec = new PBEParameterSpec( this.getSalt(), this.getCount() );
-            salt = paramSpec.getSalt();
-            cipher.init( mode, key, paramSpec );   
-            //algorithmParameters = cipher.getParameters();
-            
-            byte[] result = cipher.doFinal(input);
-            iv = cipher.getIV(); // AES has 128bit block size 
-            
-            // Salt and IV need to be stored with the result, otherwise we can't decrypt the message later.
-            ciphertext = new byte[salt.length + iv.length + result.length];
-            
-            System.arraycopy(salt, 0, ciphertext, 0, salt.length);
-            System.arraycopy(iv, 0, ciphertext, salt.length, iv.length);
-            System.arraycopy(result, 0, ciphertext, salt.length + iv.length, result.length);// push after salt and iv  
-        }
-        return ciphertext;
-    }
-    
-    private byte[] generateSalt() throws GeneralSecurityException {
-        SecureRandom random;
-        try {
-            random = SecureRandom.getInstance("SHA1PRNG");
-            byte[] salt = new byte[SALT_SIZE / 8];
-            random.nextBytes(salt);
-            return salt;
-        } catch (NoSuchAlgorithmException e) {
-            throw new GeneralSecurityException(e);  
-        }
-    }
-
-}
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 1753d7c..724afaf 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
@@ -33,7 +33,6 @@
 
 import javax.crypto.Cipher;
 
-import org.apache.fulcrum.jce.crypto.CryptoStreamFactoryImpl;
 import org.apache.fulcrum.jce.crypto.PasswordFactory;
 import org.apache.fulcrum.jce.crypto.StreamUtil;
 import org.apache.fulcrum.jce.crypto.algo.CryptoStreamGCMImpl;
@@ -45,8 +44,27 @@
  * 
  * 
  **/
-public abstract class CryptoStreamFactoryJ8Template extends CryptoStreamFactoryImpl implements CryptoStreamFactoryJ8
+public abstract class CryptoStreamFactoryJ8Template /*  extends CryptoStreamFactoryImpl*/ implements CryptoStreamFactoryJ8
 {
+	
+	/** the salt for the algorithm */
+    protected byte[] salt;
+
+    /** the count paramter for the algorithm */
+    protected int count;
+
+    /** the name of the JCE provider */
+    protected String providerName;
+
+    /** the algorithm to use */
+    protected String algorithm;
+    
+    /**
+     * The JCE provider name known to work. If the value
+     * is set to null an appropriate provider will be
+     * used.
+     */
+    protected static final String PROVIDERNAME = null;
 
     protected static final int SALT_SIZE = 16; //might increase cipher length
     protected static final int KEY_SIZE = 256;
@@ -62,6 +80,8 @@
 
     /**
      * Factory method to get a default instance
+     * 
+     * @param type the @see {@link TYPES} of the instance.
      * @return an instance of the CryptoStreamFactory
      */
     public static CryptoStreamFactoryJ8 getInstance(TYPES type) 
@@ -90,7 +110,7 @@
      *
      * @param salt the salt for the PBE algorithm
      * @param count the iteration for PBEParameterSpec
-     * @paramn type {@link TYPES}
+     * @param type {@link TYPES} what type the algorithm will be
      */
     public CryptoStreamFactoryJ8Template( byte[] salt, int count, TYPES type)
     {
@@ -105,7 +125,7 @@
     /**
      * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getSmartInputStream(java.io.InputStream)
      */
-    @Override
+
     public InputStream getSmartInputStream(InputStream is)
         throws GeneralSecurityException, IOException
     {
@@ -118,7 +138,6 @@
     /**
      * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getInputStream(java.io.InputStream,char[])
      */
-    @Override
     public InputStream getInputStream( InputStream is, char[] password )
         throws GeneralSecurityException, IOException
     {
@@ -127,8 +146,6 @@
         return eis;
     }
 
-    
-    @Override
     public OutputStream getOutputStream(InputStream is, OutputStream os, char[] password)
             throws GeneralSecurityException, IOException {
         byte[] encrypted =  this.createCipher( is, Cipher.ENCRYPT_MODE, password );
@@ -136,6 +153,61 @@
         StreamUtil.copy(eis, os);
         return os;
     }
+    
+    /**
+     * resets the default instances
+     */
+    public static void resetInstances()
+    {
+        CryptoStreamFactoryJ8Template.instances.clear();
+    }
+    
+    /**
+     * Set the default instances from an external application.
+     * @param instances the new default instances map
+     * @throws Exception if instances are null
+     */
+    public static void setInstances(Map<TYPES,CryptoStreamFactoryJ8Template> instances ) throws Exception
+    {
+    	if (instances == null) throw new Exception("setting instances to null not allowed!");
+        CryptoStreamFactoryJ8Template.instances = instances;
+    }
+    
+    /** not used / implemented methods **/
+    
+    @Override
+	public InputStream getInputStream(InputStream is, String decryptionMode)
+			throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+
+	@Override
+	public InputStream getInputStream(InputStream is, String decryptionMode, char[] password)
+			throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+
+	@Override
+	public InputStream getInputStream(InputStream is) throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+
+	@Override
+	public InputStream getSmartInputStream(InputStream is, char[] password)
+			throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+
+	@Override
+	public OutputStream getOutputStream(OutputStream os) throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+
+	@Override
+	public OutputStream getOutputStream(OutputStream os, char[] password) throws GeneralSecurityException, IOException {
+		throw new UnsupportedOperationException("not implemented");
+	}
+    /** not used methods end **/
 
     /**
      * Create a PBE key.
@@ -151,19 +223,31 @@
     /**
      * Create a Cipher.
      *
+     * @param is the input stream
      * @param mode the cipher mode
      * @param password the password
      * @return an instance of a cipher
+     * @return the cipher as byte array
      * @throws GeneralSecurityException creating a cipher failed
      * @throws IOException creating a cipher failed
      */
     protected abstract byte[] createCipher(InputStream is, int mode, char[] password )
         throws GeneralSecurityException, IOException;
     
+    /**
+     * creates salt from {@link SecureRandom#getInstance(String)} by default was algorithm SHA1PRNG
+     * 
+     * changed to {@link SecureRandom#getInstanceStrong()} and let the system decide, what PRNG to use for salt random.
+     * 
+     * salt size by default @link {@value #SALT_SIZE}.
+     * 
+     * @return the generated salt as byte array
+     * @throws GeneralSecurityException if no algo could be found.
+     */
     protected byte[] generateSalt() throws GeneralSecurityException {
         SecureRandom random;
         try {
-            random = SecureRandom.getInstance("SHA1PRNG");
+            random = SecureRandom.getInstanceStrong();
             byte[] salt = new byte[SALT_SIZE ];
             random.nextBytes(salt);
             return salt;
@@ -172,4 +256,36 @@
         }
     }
 
+	public byte[] getSalt() {
+		return salt;
+	}
+
+	public void setSalt(byte[] salt) {
+		this.salt = salt;
+	}
+
+	public int getCount() {
+		return count;
+	}
+
+	public void setCount(int count) {
+		this.count = count;
+	}
+
+	public String getProviderName() {
+		return providerName;
+	}
+
+	public void setProviderName(String providerName) {
+		this.providerName = providerName;
+	}
+
+	public String getAlgorithm() {
+		return algorithm;
+	}
+
+	public void setAlgorithm(String algorithm) {
+		this.algorithm = algorithm;
+	}
+
 }
diff --git a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java
index 8e67fe9..a4bbc2e 100644
--- a/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java
+++ b/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java
@@ -32,125 +32,113 @@
 import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8.TYPES;
 
 /**
- * Helper class to provde generic functions to work with CryptoStreams.
+ * Helper class to provide generic functions to work with CryptoStreams.
  *
  * The code uses parts from Markus Hahn's Blowfish library found at
  * http://blowfishj.sourceforge.net/
  *
  * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
  * @author <a href="mailto:maakus@earthlink.net">Markus Hahn</a>
+ * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
  */
-public final class CryptoUtilJ8 extends CryptoUtil 
-{
+public final class CryptoUtilJ8 extends CryptoUtil {
 
-    /** the typed default instances */    
-    private static Map<TYPES,CryptoUtilJ8> cryptoUtilJ8s = new ConcurrentHashMap<>();
-    
+	/** the typed default instances */
+	private static Map<TYPES, CryptoUtilJ8> cryptoUtilJ8s = new ConcurrentHashMap<>();
+
 	// default see instance
-    public TYPES type;
-    
-    public TYPES getType() 
-    {
-        return type;
-    }
+	public TYPES type;
 
-    
-    
-    /**
-     * Factory method to get a default instance
-     * @param type 
-     * @return an instance of the CryptoStreamFactory
-     */
-    public static CryptoUtilJ8 getInstance(TYPES type)
-    {
-        synchronized (CryptoUtilJ8.class) 
-        {
-            if( !cryptoUtilJ8s.containsKey(type) )
-            {
-                cryptoUtilJ8s.put(type, new CryptoUtilJ8(type) );
-            }
-            return cryptoUtilJ8s.get(type);
-        }
-    }
-    
-    /**
-     * Factory method to get a default instance
-     * 
-     * default type PDC
-     * @return an instance of the CryptoStreamFactory
-     */
-    public static CryptoUtilJ8 getInstance()
-    {
-        synchronized (CryptoUtilJ8.class) 
-        {
-            TYPES defaultType = TYPES.PBE;
-            if( cryptoUtilJ8s.isEmpty() && !cryptoUtilJ8s.containsKey(defaultType) )
-            {
-                cryptoUtilJ8s.put(defaultType, new CryptoUtilJ8(defaultType) );
-            }
-            return cryptoUtilJ8s.get(defaultType);
-        }
-    }
-    
-    private CryptoUtilJ8(TYPES type) 
-    {
-        super();
-        this.type = type;
-    }
-    
-    private CryptoUtilJ8() 
-    {
-        super();
-    }
+	public TYPES getType() {
+		return type;
+	}
 
-    /**
-     * Copies from a source to a target object using encryption and a caller
-     * supplied CryptoStreamFactory.
-     *
-     * @param factory  the factory to create the crypto streams
-     * @param source   the source object
-     * @param target   the target object
-     * @param password the password to use for encryption
-     * @throws GeneralSecurityException accessing JCE failed
-     * @throws IOException              accessing the source failed
-     */
-    @Override
-    public void encrypt(CryptoStreamFactory factory, Object source, Object target, char[] password)
-            throws GeneralSecurityException, IOException 
-    {
-        InputStream is  = StreamUtil.createInputStream(source);
-        OutputStream os = StreamUtil.createOutputStream(target);
-        OutputStream eos = ( (CryptoStreamFactoryJ8) factory).getOutputStream(is, os, password);
-        // StreamUtil.copy( is, eos );
-    }
-    
-    /**
-     * Copies from a source to a target object using decryption and a caller-suppier
-     * CryptoStreamFactory.
-     *
-     * @param factory  the factory to create the crypto streams
-     * @param source   the source object
-     * @param target   the target object
-     * @param password the password to use for decryption
-     * @throws GeneralSecurityException accessing JCE failed
-     * @throws IOException              accessing the source failed
-     */
-    @Override
-    protected void decrypt(CryptoStreamFactory factory, Object source, Object target, char[] password)
-            throws GeneralSecurityException, IOException 
-    {
-        InputStream is = StreamUtil.createInputStream(source);
-        OutputStream os = StreamUtil.createOutputStream(target);
-        InputStream dis = factory.getInputStream(is, password);
-        StreamUtil.copy(dis, os);
-    }
+	/**
+	 * Factory method to get a default instance
+	 * 
+	 * @param type one of the enum {@link TYPES}.
+	 * @return an instance of the CryptoStreamFactory
+	 */
+	public static CryptoUtilJ8 getInstance(TYPES type) {
+		synchronized (CryptoUtilJ8.class) {
+			if (!cryptoUtilJ8s.containsKey(type)) {
+				cryptoUtilJ8s.put(type, new CryptoUtilJ8(type));
+			}
+			return cryptoUtilJ8s.get(type);
+		}
+	}
 
-    /**
-     * 
-     * @return the CryptoStreamFactory to be used
-     */
-    public CryptoStreamFactory getCryptoStreamFactory() 
-    {
-            return CryptoStreamFactoryJ8Template.getInstance(type);
-    }
+	/**
+	 * Factory method to get a default instance
+	 * 
+	 * default type PDC
+	 * 
+	 * @return an instance of the CryptoStreamFactory
+	 */
+	public static CryptoUtilJ8 getInstance() {
+		synchronized (CryptoUtilJ8.class) {
+			TYPES defaultType = TYPES.PBE;
+			if (cryptoUtilJ8s.isEmpty() && !cryptoUtilJ8s.containsKey(defaultType)) {
+				cryptoUtilJ8s.put(defaultType, new CryptoUtilJ8(defaultType));
+			}
+			return cryptoUtilJ8s.get(defaultType);
+		}
+	}
+
+	private CryptoUtilJ8(TYPES type) {
+		super();
+		this.type = type;
+	}
+
+	private CryptoUtilJ8() {
+		super();
+	}
+
+	/**
+	 * Copies from a source to a target object using encryption and a caller
+	 * supplied CryptoStreamFactory.
+	 *
+	 * @param factory  the factory to create the crypto streams
+	 * @param source   the source object
+	 * @param target   the target object
+	 * @param password the password to use for encryption
+	 * @throws GeneralSecurityException accessing JCE failed
+	 * @throws IOException              accessing the source failed
+	 */
+	@Override
+	public void encrypt(CryptoStreamFactory factory, Object source, Object target, char[] password)
+			throws GeneralSecurityException, IOException {
+		InputStream is = StreamUtil.createInputStream(source);
+		OutputStream os = StreamUtil.createOutputStream(target);
+		OutputStream eos = ((CryptoStreamFactoryJ8) factory).getOutputStream(is, os, password);
+		// StreamUtil.copy( is, eos );
+	}
+
+	/**
+	 * Copies from a source to a target object using decryption and a caller-suppier
+	 * CryptoStreamFactory.
+	 *
+	 * @param factory  the factory to create the crypto streams
+	 * @param source   the source object
+	 * @param target   the target object
+	 * @param password the password to use for decryption
+	 * @throws GeneralSecurityException accessing JCE failed
+	 * @throws IOException              accessing the source failed
+	 */
+	@Override
+	protected void decrypt(CryptoStreamFactory factory, Object source, Object target, char[] password)
+			throws GeneralSecurityException, IOException {
+		InputStream is = StreamUtil.createInputStream(source);
+		OutputStream os = StreamUtil.createOutputStream(target);
+		InputStream dis = factory.getInputStream(is, password);
+		StreamUtil.copy(dis, os);
+	}
+
+	/**
+	 * 
+	 * @return the CryptoStreamFactory to be used
+	 */
+	public CryptoStreamFactory getCryptoStreamFactory() {
+		return CryptoStreamFactoryJ8Template.getInstance(type);
+	}
 }
diff --git a/src/test/log4j2.xml b/src/test/log4j2.xml
index ee9dd06..1846038 100644
--- a/src/test/log4j2.xml
+++ b/src/test/log4j2.xml
@@ -30,10 +30,14 @@
 	    </File>
     </Appenders>
     <Loggers>
-        <Logger name="org.apache.fulcrum.jce.crypto" level="debug" additivity="false">
+      <Logger name="org.apache.fulcrum.jce.crypto" level="debug" additivity="false">
             <AppenderRef ref="console"/>
             <AppenderRef ref="logfile"/>
-        </Logger>
+       </Logger>
+       <Logger name="org.apache.fulcrum.jce" level="debug" additivity="false">
+            <AppenderRef ref="console"/>
+            <AppenderRef ref="logfile"/>
+       </Logger>
       <Logger name="org.apache.fulcrum" level="info" additivity="false">
           <AppenderRef ref="console"/>
           <AppenderRef ref="logfile"/>
diff --git a/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ParameterizedTest.java b/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ParameterizedTest.java
index 3339354..ed3f275 100644
--- a/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ParameterizedTest.java
+++ b/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ParameterizedTest.java
@@ -1,6 +1,5 @@
 package org.apache.fulcrum.jce.crypto.extended;
 
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -24,309 +23,338 @@
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
 
-
 /**
  * Test suite for crypto functionality
  *
  * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
  */
 public class CryptoUtilJ8ParameterizedTest {
-    /** the password to be used */
-    private String password;
+	/** the password to be used */
+	private String password;
 
-    /** the test data directory */
-    private File testDataDirectory;
+	/** the test data directory */
+	private File testDataDirectory;
 
-    /** the temp data director */
-    private File tempDataDirectory;
-    
-    private List<CryptoUtilJ8> cryptoUtilJ8s = new ArrayList<>();
-    
-    private static Logger log = LogManager.getLogger(CryptoUtilJ8ParameterizedTest.class);
+	/** the temp data director */
+	private File tempDataDirectory;
 
-    /**
-     * Constructor
-     */
-    public CryptoUtilJ8ParameterizedTest() {
+	private List<CryptoUtilJ8> cryptoUtilJ8s = new ArrayList<>();
 
-        this.password = "mysecret";
-        this.testDataDirectory = new File("./src/test/data");
-        this.tempDataDirectory = new File("./target/temp");
-        this.tempDataDirectory.mkdirs();
-    }
+	private static Logger log = LogManager.getLogger(CryptoUtilJ8ParameterizedTest.class);
 
-    
+	/**
+	 * Constructor
+	 */
+	public CryptoUtilJ8ParameterizedTest() {
+
+		this.password = "mysecret";
+		this.testDataDirectory = new File("./src/test/data");
+		this.tempDataDirectory = new File("./target/temp");
+		this.tempDataDirectory.mkdirs();
+	}
+
 //    @ParameterizedTest
 //    @EnumSource( TYPES.class )
 //    public void setUp(TYPES type) throws Exception {
 //        cryptoUtilJ8 = CryptoUtilJ8.getInstance(type); // (TYPES.PBE);
 //    }
 
-    /**
-     * @return Returns the password.
-     */
-    protected char[] getPassword() {
-        return password.toCharArray();
-    }
+	/**
+	 * @return Returns the password.
+	 */
+	protected char[] getPassword() {
+		return password.toCharArray();
+	}
 
-    /**
-     * @return Returns the tempDataDirectory.
-     */
-    protected File getTempDataDirectory() {
-        return tempDataDirectory;
-    }
+	/**
+	 * @return Returns the tempDataDirectory.
+	 */
+	protected File getTempDataDirectory() {
+		return tempDataDirectory;
+	}
 
-    /**
-     * @return Returns the testDataDirectory.
-     */
-    protected File getTestDataDirectory() {
-        return testDataDirectory;
-    }
-    
-    @AfterEach
-    public void setup() {
-        cryptoUtilJ8s.clear(); 
-    }
-    
-    /** Encrypt a text file 
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testTextEncryption(TYPES type)  {
-        
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-        File sourceFile = new File(this.getTestDataDirectory(), "plain.txt");
-        File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.txt");
-        
-        cryptoUtilJ8s.forEach(cuj8 -> {
-            try {
-                log.info("checking "+ cuj8.getType());
-                cuj8.encrypt(sourceFile, targetFile, this.getPassword());
-            } catch (GeneralSecurityException e) {
-                e.printStackTrace();
-                fail();
-            } catch (IOException e) {
-                e.printStackTrace();
-                fail();
-            }
-        } );
-    }
+	/**
+	 * @return Returns the testDataDirectory.
+	 */
+	protected File getTestDataDirectory() {
+		return testDataDirectory;
+	}
 
-    /** Decrypt a text file 
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testTextDecryption(TYPES type) {
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-            cryptoUtilJ8s.forEach(cuj8 -> {
-                log.info("checking "+ cuj8.getType());
-                try {
-                    File sourceFile = new File(this.getTestDataDirectory(), "plain.txt");
-                    File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.txt");
-                    cuj8.encrypt(sourceFile, targetFile, this.getPassword());
-                    
-                    File sourceFile2 = targetFile;
-                    File targetFile2 = new File(this.getTempDataDirectory(), "plain.j8.dec.txt");
-                    cuj8.decrypt(sourceFile2, targetFile2.getAbsolutePath(), this.getPassword());
-                    assertEquals(
-                            new String(Files.readAllBytes( Paths.get(sourceFile.toURI())) ), 
-                            new String(Files.readAllBytes( Paths.get(targetFile2.toURI())) )
-                            );
-                } catch (GeneralSecurityException | IOException e) {
-                    e.printStackTrace();
-                    fail();
-                }
-            });
-    }
-    
-    /** Encrypt a PDF file 
-     * 
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testPdfEncryption(TYPES type) {
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-        File sourceFile = new File(this.getTestDataDirectory(), "plain.pdf");
-        File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.pdf");
-        cryptoUtilJ8s.forEach(cuj8 -> { 
-            try {
-                cuj8.encrypt(sourceFile, targetFile, this.getPassword());
-            } catch (GeneralSecurityException | IOException e) {
-                e.printStackTrace();
-                fail();
-            }    
-        });        
-    }
+	@AfterEach
+	public void setup() {
+		cryptoUtilJ8s.clear();
+	}
 
-    /** Decrypt a PDF file 
-     * 
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testPdfDecryption(TYPES type)  {
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-        //testPdfEncryption();
-        cryptoUtilJ8s.forEach(cuj8 -> { 
-            try {
-                File sourceFile = new File(this.getTestDataDirectory(), "plain.pdf");
-                File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.pdf");
-                cuj8.encrypt(sourceFile, targetFile, this.getPassword());
-                
-                File sourceFile2 = targetFile;
-                File targetFile2 = new File(this.getTempDataDirectory(), "plain.j8.dec.pdf");
-                cuj8.decrypt(sourceFile2, targetFile2, this.getPassword());
-                
-                assertEquals(
-                        new String(Files.readAllBytes( Paths.get(sourceFile.toURI())) ), 
-                        new String(Files.readAllBytes( Paths.get(targetFile2.toURI())) )
-                        );
-            } catch (GeneralSecurityException | IOException e) {
-                e.printStackTrace();
-                fail();
-            }    
-        }); 
+	/**
+	 * Parameterized Test
+	 * 
+	 * Encrypt a text file
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testTextEncryption(TYPES type) {
 
-    }
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		File sourceFile = new File(this.getTestDataDirectory(), "plain.txt");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.txt");
 
-    /** Test encryption and decryption of Strings
-     * 
-     *  @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testStringEncryption(TYPES type) {
-        CryptoUtilJ8 cuj8= CryptoUtilJ8.getInstance(type);
-        char[] testVector = new char[513];
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			try {
+				log.info("checking " + cuj8.getType());
+				cuj8.encrypt(sourceFile, targetFile, this.getPassword());
+			} catch (GeneralSecurityException e) {
+				e.printStackTrace();
+				fail();
+			} catch (IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+		});
+	}
 
-        for (int i = 0; i < testVector.length; i++) {
-            testVector[i] = (char) i;
-        }
+	/**
+	 * Parameterized Test Decrypt a text file
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testTextDecryption(TYPES type) {
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			log.info("checking " + cuj8.getType());
+			try {
+				File sourceFile = new File(this.getTestDataDirectory(), "plain.txt");
+				File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.txt");
+				cuj8.encrypt(sourceFile, targetFile, this.getPassword());
 
-        String source = new String(testVector);
-        String cipherText = null;
-        String plainText = null;
-        try {
-            log.debug("without clearTextHeader");
-            cipherText = cuj8.encryptString(source, this.getPassword());
-            plainText = cuj8.decryptString(cipherText, this.getPassword());
-            assertEquals(source, plainText, source +" is not equal with " + plainText);
-            
-            log.debug("with clearTextHeader in encrypted string:" + CryptoParametersJ8.CLEAR_CODE_J8);
-            String cipherText2 = cuj8.encryptStringWithClearCode(source, this.getPassword());
-            
-            assertTrue(cipherText2.startsWith(CryptoParametersJ8.CLEAR_CODE_J8), cipherText2 +" does not start with " + CryptoParametersJ8.CLEAR_CODE_J8);
-            String plainText2 = cuj8.decryptStringWithClearCode(cipherText2, this.getPassword());
-            assertEquals(source, plainText2, source +" is not equal with " + plainText);
-            
-        } catch (GeneralSecurityException | IOException e) {
-            e.printStackTrace();
-            fail();
-        }
-    }
+				File sourceFile2 = targetFile;
+				File targetFile2 = new File(this.getTempDataDirectory(), "plain.j8.dec.txt");
+				cuj8.decrypt(sourceFile2, targetFile2.getAbsolutePath(), this.getPassword());
+				assertEquals(new String(Files.readAllBytes(Paths.get(sourceFile.toURI()))),
+						new String(Files.readAllBytes(Paths.get(targetFile2.toURI()))));
+			} catch (GeneralSecurityException | IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+		});
+	}
 
-    /** Test encryption and decryption of Strings
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testStringHandling(TYPES type)  {
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-        String source = "Nobody knows the toubles I have seen ...";
-        cryptoUtilJ8s.forEach(cuj8 -> { 
-            String cipherText;
-            try {
-                cipherText = cuj8.encryptString(source, this.getPassword());
-                String plainText = cuj8.decryptString(cipherText, this.getPassword());
-                assertEquals(source, plainText);   
-            } catch (GeneralSecurityException | IOException e) {
-                e.printStackTrace();
-                fail();
-            }
-         
-        });
+	/**
+	 * Parameterized Test
+	 * 
+	 * Encrypt a PDF file
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testPdfEncryption(TYPES type) {
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		File sourceFile = new File(this.getTestDataDirectory(), "plain.pdf");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.pdf");
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			try {
+				cuj8.encrypt(sourceFile, targetFile, this.getPassword());
+			} catch (GeneralSecurityException | IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+		});
+	}
 
-    }
+	/**
+	 * Parameterized Test Decrypt a PDF file
+	 *
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testPdfDecryption(TYPES type) {
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		// testPdfEncryption();
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			try {
+				File sourceFile = new File(this.getTestDataDirectory(), "plain.pdf");
+				File targetFile = new File(this.getTempDataDirectory(), "plain.j8.enc.pdf");
+				cuj8.encrypt(sourceFile, targetFile, this.getPassword());
 
-    /** Test creating a password
-     * @throws Exception Generic exception
-     */
-    @Test
-    public void testPasswordFactory() throws Exception {
-        char[] result = null;
-        result = PasswordFactory.getInstance("SHA-256").create();
-        log.info("random pw:" + new String(result));
-        result = PasswordFactory.getInstance("SHA-256",10_000).create(this.getPassword());
-        log.info("password pw with seed:" + new String(result));
-        assertNotNull(result);
-        return;
-    }
-    
-    /** Test encryption and decryption of binary data
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testBinaryHandling(TYPES type) throws Exception {
-        cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
-        cryptoUtilJ8s.forEach(cuj8 -> { 
-            byte[] source = new byte[256];
-            byte[] result = null;
+				File sourceFile2 = targetFile;
+				File targetFile2 = new File(this.getTempDataDirectory(), "plain.j8.dec.pdf");
+				cuj8.decrypt(sourceFile2, targetFile2, this.getPassword());
 
-            for (int i = 0; i < source.length; i++) {
-                source[i] = (byte) i;
-            }
+				assertEquals(new String(Files.readAllBytes(Paths.get(sourceFile.toURI()))),
+						new String(Files.readAllBytes(Paths.get(targetFile2.toURI()))));
+			} catch (GeneralSecurityException | IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+		});
 
-            ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
-            ByteArrayOutputStream plainText = new ByteArrayOutputStream();
-            try {
-                cuj8.encrypt(source, cipherText, this.getPassword());
-                cuj8.decrypt(cipherText, plainText, this.getPassword());
-            } catch (GeneralSecurityException | IOException e) {
-                e.printStackTrace();
-                fail();
-            }
-            result = plainText.toByteArray();
+	}
 
-            for (int i = 0; i < source.length; i++) {
-                if (source[i] != result[i]) {
-                    fail("Binary data are different at position " + i);
-                }
-            }
-        });
+	/**
+	 * Parameterized Test Test encryption and decryption of Strings
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testStringEncryption(TYPES type) {
+		CryptoUtilJ8 cuj8 = CryptoUtilJ8.getInstance(type);
+		char[] testVector = new char[513];
 
-       
+		for (int i = 0; i < testVector.length; i++) {
+			testVector[i] = (char) i;
+		}
 
-    }
-    
-    /** Test encryption and decryption of Strings 
-     * @throws Exception Generic exception
-     */
-    @ParameterizedTest
-    @EnumSource( TYPES.class )
-    public void testStringWithPasswordEncryption(TYPES type) {
-        char[] password = "57cb-4a23-d838-45222".toCharArray();
-        String source = "e02c-3b76-ff1e-5d9a1";
-        CryptoUtilJ8 cuj8 = CryptoUtilJ8.getInstance(type);
-        log.debug("checking "+ cuj8.getType());
-        String cipherText = null;
-        try {
-            cipherText = cuj8.encryptString(source, password);
-            log.info(cipherText);// about 128 
-            log.info("length for " + cuj8.getType() + " is:" +cipherText.length());// about 128
-            if (cuj8.type == TYPES.PBE) {
-                assertEquals(128, cipherText.length()); // 128bytes + 10 bytes for cleartext
-            } 
-            CryptoStreamFactoryJ8Template.setInstance(null);
-            String plainText = cuj8.decryptString(cipherText, password);
-            assertEquals(source, plainText);
-        } catch (GeneralSecurityException | IOException e) {
-            e.printStackTrace();
-            fail();
-        }      
-    }
+		String source = new String(testVector);
+		String cipherText = null;
+		String plainText = null;
+		try {
+			log.info("Test without clearTextHeader");
+			cipherText = cuj8.encryptString(source, this.getPassword());
+			// log.debug(cipherText);
+			plainText = cuj8.decryptString(cipherText, this.getPassword());
+			assertEquals(source, plainText, source + " is not equal with " + plainText);
+
+			log.info(String.format("Test with clearTextHeader %s in encrypted string.",
+					CryptoParametersJ8.CLEAR_CODE_J8));
+			String cipherText2 = cuj8.encryptStringWithClearCode(source, this.getPassword());
+			// log.debug(cipherText2);
+			assertTrue(cipherText2.startsWith(CryptoParametersJ8.CLEAR_CODE_J8),
+					String.format("%s does not start with '%s'", cipherText2, CryptoParametersJ8.CLEAR_CODE_J8));
+			String plainText2 = cuj8.decryptStringWithClearCode(cipherText2, this.getPassword());
+			assertEquals(source, plainText2, String.format("%s is not equal with %s", source, plainText));
+
+		} catch (GeneralSecurityException | IOException e) {
+			e.printStackTrace();
+			fail();
+		}
+	}
+
+	/**
+	 * Parameterized Test Test encryption and decryption of Strings
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testStringHandling(TYPES type) {
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		String source = "Nobody knows the toubles I have seen ...";
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			String cipherText;
+			try {
+				cipherText = cuj8.encryptString(source, this.getPassword());
+				String plainText = cuj8.decryptString(cipherText, this.getPassword());
+				assertEquals(source, plainText);
+			} catch (GeneralSecurityException | IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+
+		});
+
+	}
+
+	/**
+	 * Test creating a password
+	 * 
+	 * @throws Exception Generic exception
+	 */
+	@Test
+	public void testPasswordFactory() throws Exception {
+		char[] result = null;
+		result = PasswordFactory.getInstance("SHA-256").create();
+		log.info("random pw:" + new String(result));
+		result = PasswordFactory.getInstance("SHA-256", 10_000).create(this.getPassword());
+		log.info("password pw with seed:" + new String(result));
+		assertNotNull(result);
+		return;
+	}
+
+	/**
+	 * Parameterized Test
+	 * 
+	 * Test encryption and decryption of binary data
+	 * 
+	 * @throws Exception Generic exception
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testBinaryHandling(TYPES type) throws Exception {
+		cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
+		cryptoUtilJ8s.forEach(cuj8 -> {
+			byte[] source = new byte[256];
+			byte[] result = null;
+
+			for (int i = 0; i < source.length; i++) {
+				source[i] = (byte) i;
+			}
+
+			ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
+			ByteArrayOutputStream plainText = new ByteArrayOutputStream();
+			try {
+				cuj8.encrypt(source, cipherText, this.getPassword());
+				cuj8.decrypt(cipherText, plainText, this.getPassword());
+			} catch (GeneralSecurityException | IOException e) {
+				e.printStackTrace();
+				fail();
+			}
+			result = plainText.toByteArray();
+
+			for (int i = 0; i < source.length; i++) {
+				if (source[i] != result[i]) {
+					fail("Binary data are different at position " + i);
+				}
+			}
+		});
+
+	}
+
+	/**
+	 * Parameterized Test
+	 * 
+	 * Test encryption and decryption of Strings
+	 * 
+	 * @param type the type to be tested based on {@link TYPES}
+	 * 
+	 */
+	@ParameterizedTest
+	@EnumSource(TYPES.class)
+	public void testStringWithPasswordEncryption(TYPES type) {
+		char[] password = "57cb-4a23-d838-45222".toCharArray();
+		String source = "e02c-3b76-ff1e-5d9a1";
+		CryptoUtilJ8 cuj8 = CryptoUtilJ8.getInstance(type);
+		log.debug("checking type " + cuj8.getType());
+		String cipherText = null;
+		try {
+			cipherText = cuj8.encryptString(source, password);
+			log.info(cipherText);// about 128
+			log.info(String.format("length for %s is %d", cuj8.getType(), cipherText.length()));// about 128
+			if (cuj8.type == TYPES.PBE) {
+				assertEquals(128, cipherText.length()); // 128bytes + 10 bytes for cleartext
+			}
+			if (cuj8.type == TYPES.GCM) {
+				assertEquals(128, cipherText.length());
+			}
+			String plainText = cuj8.decryptString(cipherText, password);
+			assertEquals(source, plainText);
+		} catch (GeneralSecurityException | IOException e) {
+			e.printStackTrace();
+			fail();
+		}
+	}
 
 }
diff --git a/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8Test.java b/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8Test.java
index b8d4e54..3c7570b 100644
--- a/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8Test.java
+++ b/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8Test.java
@@ -64,8 +64,10 @@
             cryptoUtilJ8s.add(CryptoUtilJ8.getInstance(type));
         }
         for (CryptoUtilJ8 cryptoUtilJ8 : cryptoUtilJ8s) {
-            log.debug("registered cryptoUtilsJ8: {}", cryptoUtilJ8.getType() );
-            log.debug( ((CryptoStreamFactoryJ8Template)cryptoUtilJ8.getCryptoStreamFactory()).getAlgorithm());
+            log.debug("registered {}: {}", cryptoUtilJ8.getClass().getSimpleName(), cryptoUtilJ8.getType() );
+            CryptoStreamFactoryJ8Template crt = ((CryptoStreamFactoryJ8Template)cryptoUtilJ8.getCryptoStreamFactory());
+            log.debug(String.format("created default crypto factory instance %s for algo %s", crt.getClass().getSimpleName(),
+            		crt.getAlgorithm()));
         }
 
     }
@@ -97,7 +99,7 @@
     }
     
     /** Encrypt a text file 
-     * @throws Exception Generic exception
+     * 
      */
     @Test
     public void testTextEncryption()  {
@@ -119,7 +121,6 @@
     }
 
     /** Decrypt a text file 
-     * @throws Exception Generic exception
      */
     @Test
     public void testTextDecryption() {           
@@ -145,7 +146,6 @@
     
     /** Encrypt a PDF file 
      * 
-     * @throws Exception Generic exception
      */
     @Test
     public void testPdfEncryption() {
@@ -163,7 +163,6 @@
 
     /** Decrypt a PDF file 
      * 
-     * @throws Exception Generic exception
      */
     @Test
     public void testPdfDecryption()  {
@@ -192,7 +191,6 @@
 
     /** Test encryption and decryption of Strings
      * 
-     *  @throws Exception Generic exception
      */
     @Test
     public void testStringEncryption() {
@@ -221,7 +219,6 @@
     }
 
     /** Test encryption and decryption of Strings
-     * @throws Exception Generic exception
      */
     @Test
     public void testStringHandling()  {
@@ -241,7 +238,8 @@
 
     }
 
-    /** Test creating a password
+    /** 
+     * Test creating a password
      * @throws Exception Generic exception
      */
     @Test
@@ -291,8 +289,8 @@
 
     }
     
-    /** Test encryption and decryption of Strings 
-     * @throws Exception Generic exception
+    /** 
+     * Test encryption and decryption of Strings 
      */
     @Test
     public void testStringWithPasswordEncryption() {
@@ -309,7 +307,7 @@
                 if (cuj8.type == TYPES.PBE) {
                     assertEquals(128, cipherText.length()); // 128bytes + 10 bytes for cleartext
                 } 
-                CryptoStreamFactoryJ8Template.setInstance(null);
+                CryptoStreamFactoryJ8Template.resetInstances();
                 String plainText = cuj8.decryptString(cipherText, password);
                 assertEquals(source, plainText);
             } catch (GeneralSecurityException | IOException e) {
diff --git a/xdocs/downloads.xml b/xdocs/downloads.xml
index c7fd4bb..ea7ceed 100644
--- a/xdocs/downloads.xml
+++ b/xdocs/downloads.xml
@@ -31,12 +31,14 @@
         </tr>
         <tr>
           <td>
-            <a href="http://www.apache.org/dyn/closer.cgi/turbine/fulcrum/fulcrum-yaafi-crypto/binaries/fulcrum-yaafi-crypto-1.0.6-bin.zip">Fulcrum's YAAFI Crypto v1.0.6</a>
-          </td>
-          <td>
+            <p><a href="http://www.apache.org/dyn/closer.cgi/turbine/fulcrum/fulcrum-yaafi-crypto/binaries/fulcrum-yaafi-crypto-1.0.6-bin.zip">Fulcrum's YAAFI Crypto v1.0.6</a>
+            </p><p>
             <a href="http://www.apache.org/dyn/closer.cgi/turbine/fulcrum/fulcrum-yaafi-crypto/binaries/fulcrum-yaafi-crypto-1.0.7-bin.zip">Fulcrum's YAAFI Crypto v1.0.7</a>
+            </p>
+            <p>
+            <a href="http://www.apache.org/dyn/closer.cgi/turbine/fulcrum/fulcrum-yaafi-crypto/binaries/fulcrum-yaafi-crypto-1.0.8-bin.zip">Fulcrum's YAAFI Crypto v1.0.8</a>
+            </p>
           </td>
-
           <td>
             <a href="announcements/announcement-1.0.6.txt">1.0.6</a>
           </td>