You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2020/07/23 11:58:44 UTC

svn commit: r1880199 [1/2] - in /turbine/fulcrum/trunk/yaafi-crypto: ./ src/changes/ src/filters/ src/java/org/apache/fulcrum/jce/crypto/ src/java/org/apache/fulcrum/jce/crypto/algo/ src/java/org/apache/fulcrum/jce/crypto/cli/ src/java/org/apache/fulcr...

Author: gk
Date: Thu Jul 23 11:58:44 2020
New Revision: 1880199

URL: http://svn.apache.org/viewvc?rev=1880199&view=rev
Log:
- updated and added tests
- replaced junit EnumSource with ArgumentsSource in CryptoUtilJ8ParameterizedTest
 (automatically converts to provided argument enum by JUnit Argument Conversion)
- check system ciphers in test and cli info (printInfo)
- dynamic clear code in CryptoParametersJ8
- fixes and cleanup of typed instances CryptoUtilJ8 and CryptoStreamFactoryJ8Template
- added documentation

Added:
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilExplicitParamsTest.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ExplicitParamsTest.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/junit5/
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/junit5/extension/
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/junit5/extension/SupportedTypeArguments.java
Modified:
    turbine/fulcrum/trunk/yaafi-crypto/pom.xml
    turbine/fulcrum/trunk/yaafi-crypto/src/changes/changes.xml
    turbine/fulcrum/trunk/yaafi-crypto/src/filters/filter-integration-test.properties
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoUtil.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
    turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/log4j2.xml
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilTest.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8ParameterizedTest.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8Test.java
    turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/extended/Main8Test.java
    turbine/fulcrum/trunk/yaafi-crypto/xdocs/index.xml

Modified: turbine/fulcrum/trunk/yaafi-crypto/pom.xml
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/pom.xml?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/pom.xml (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/pom.xml Thu Jul 23 11:58:44 2020
@@ -20,8 +20,9 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <parent>
     <artifactId>turbine-parent</artifactId>
-       <groupId>org.apache.turbine</groupId>
-       <version>7</version>
+    <groupId>org.apache.turbine</groupId>
+    <version>7</version>
+    <relativePath />
   </parent>
 
   <modelVersion>4.0.0</modelVersion>
@@ -206,6 +207,15 @@
 
         </executions>
       </plugin>
+      
+      <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <configuration>
+            <forkCount>1</forkCount>
+            <reuseFork>true</reuseFork>
+           </configuration>
+        </plugin>
     </plugins>
   </build>
   

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/changes/changes.xml?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/changes/changes.xml (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/changes/changes.xml Thu Jul 23 11:58:44 2020
@@ -25,6 +25,9 @@
 
   <body>
     <release version="1.0.8" date="as in SVN">
+    <action dev="gk" type="update">
+        Updated Tests using Junit extension. More flexible comman line utility, defining CLI2 as manifest main class. Fine tuning clear code prefix and added integration-test
+      </action>
       <action dev="gk" type="update">
         Added two Java 8 implementations based on PBE/AES (PBEWithHmacSHA256AndAES_256) or GCM (AES/GCM/NoPadding) encryption.
       </action>

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/filters/filter-integration-test.properties
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/filters/filter-integration-test.properties?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/filters/filter-integration-test.properties (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/filters/filter-integration-test.properties Thu Jul 23 11:58:44 2020
@@ -1,2 +1,2 @@
-#Mon, 20 Jul 2020 13:46:30 +0200
-password_encrypted=1796bc2d3d02f478bb042ed24740e98a2654fa47bd331266e1a7b682c2d37a2d0254dc61dd71badfe1c22b745f039041
+#Thu, 23 Jul 2020 13:53:53 +0200
+password_encrypted=0e88b1ae1cc8bcee9df12575805fbb770d70123259929778998a8285730b1d53453632a50fd9cac77d8a8f1603b622f4

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoStreamFactoryImpl.java Thu Jul 23 11:58:44 2020
@@ -122,6 +122,27 @@ public class CryptoStreamFactoryImpl ext
         this.providerName = PROVIDERNAME;
         this.algorithm = CryptoParameters.ALGORITHM;
     }
+    
+
+    /**
+     * Factory method to get a default instance
+     * 
+     * @param salt the salt for the PBE algorithm
+     * @param count the iteration for PBEParameterSpec
+     * @return an instance of the CryptoStreamFactory
+     * 
+     */
+    public static CryptoStreamFactory getInstance( byte[] salt, int count)
+    {
+        synchronized(CryptoStreamFactoryImpl.class ) {
+            if( CryptoStreamFactoryImpl.instance == null )
+            {
+                CryptoStreamFactoryImpl.instance = new CryptoStreamFactoryImpl(salt, count);
+            }
+    
+            return CryptoStreamFactoryImpl.instance;
+        }
+    }
 
     /**
      * @see org.apache.fulcrum.jce.crypto.CryptoStreamFactory#getSmartInputStream(java.io.InputStream,char[])

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoUtil.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoUtil.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoUtil.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/CryptoUtil.java Thu Jul 23 11:58:44 2020
@@ -26,6 +26,8 @@ import java.io.OutputStream;
 import java.security.GeneralSecurityException;
 
 import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8;
+import org.apache.fulcrum.jce.crypto.extended.CryptoStreamFactoryJ8Template;
+import org.apache.fulcrum.jce.crypto.extended.CryptoUtilJ8;
 
 /**
  * Helper class to provde generic functions to work with CryptoStreams.
@@ -43,7 +45,7 @@ public class CryptoUtil {
     private static CryptoUtil instance;
     
     
-    private CryptoStreamFactory cryptoStreamFactory;
+    protected CryptoStreamFactory cryptoStreamFactory;
     
     /**
      * Factory method to get a default instance
@@ -64,6 +66,29 @@ public class CryptoUtil {
     protected CryptoUtil() {
         cryptoStreamFactory = CryptoStreamFactoryImpl.getInstance();
     }
+    
+    /**
+     * Factory method to get a default instance
+     * 
+     * @param salt the salt for the PBE algorithm
+     * @param count the iteration for PBEParameterSpec
+     * @return an instance of the CryptoUtil
+     */
+    public synchronized static CryptoUtil getInstance(byte[] salt, int count) {
+        if (CryptoUtil.instance == null) {
+            CryptoUtil.instance = new CryptoUtil(salt, count);
+        }
+
+        return CryptoUtil.instance;
+    }
+    
+    /**
+     *  @param salt the salt for the PBE algorithm
+     *  @param count the iteration for PBEParameterSpec
+     */
+    protected CryptoUtil(byte[] salt, int count) {
+        cryptoStreamFactory = CryptoStreamFactoryImpl.getInstance(salt, count);
+    }
 
     /**
      * Copies from a source to a target object using encryption
@@ -100,7 +125,7 @@ public class CryptoUtil {
 
     
     /**
-     * Encrypts a string into a hex string using {@link CryptoParametersJ8#CLEAR_CODE_J8}
+     * Encrypts a string into a hex string using {@link CryptoParametersJ8#CLEAR_CODE_DEFAULT}
      *
      * @param plainText the plain text to be encrypted
      * @param password  the password for encryption
@@ -138,10 +163,12 @@ public class CryptoUtil {
      */
     public String encryptString(CryptoStreamFactory factory, String plainText, char[] password, boolean withClearCode)
             throws GeneralSecurityException, IOException {
-        ByteArrayOutputStream bais = new ByteArrayOutputStream();
-        encrypt(factory, plainText, bais, password);
-        return (withClearCode)? CryptoParametersJ8.CLEAR_CODE_J8 + HexConverter.toString(bais.toByteArray()):
-            HexConverter.toString(bais.toByteArray());
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        encrypt(factory, plainText, baos, password);
+        String prefix =  (withClearCode)? (this instanceof CryptoUtilJ8)?
+        		((CryptoStreamFactoryJ8Template)((CryptoUtilJ8)this).getCryptoStreamFactory()).getType().getClearCode()
+            	: CryptoParametersJ8.CLEAR_CODE_DEFAULT: "";
+        return prefix + HexConverter.toString(baos.toByteArray());
     }
     
     /**
@@ -161,7 +188,9 @@ public class CryptoUtil {
      * Decrypts an encrypted string into the plain text. The encrypted string must
      * be a hex string created by encryptString.
      * 
-     * Decrypts encrypted text after {@link CryptoParametersJ8#CLEAR_CODE_J8}.
+     * Decrypts encrypted text after {@link CryptoParametersJ8#CLEAR_CODE_DEFAULT}.
+     * 
+     * Removes ClearCode length of 10 bit, before decrpyting expected as prefix.
      *
      * @param cipherText the encrypted text to be decrypted
      * @param password   the password for decryption
@@ -170,7 +199,7 @@ public class CryptoUtil {
      * @throws IOException              accessing the souce failed
      */
     public String decryptStringWithClearCode(String cipherText, char[] password) throws GeneralSecurityException, IOException {
-        return decryptString(getCryptoStreamFactory(), cipherText.substring(CryptoParametersJ8.CLEAR_CODE_J8.length()), password);
+        return decryptString(getCryptoStreamFactory(), cipherText.substring(10), password);
     }
 
     /**
@@ -200,7 +229,7 @@ public class CryptoUtil {
      */
     public String decryptString(String cipherText, char[] password, boolean withClearCode) throws GeneralSecurityException, IOException {
         return decryptString(getCryptoStreamFactory(), withClearCode?
-                cipherText.substring(CryptoParametersJ8.CLEAR_CODE_J8.length()):
+                cipherText.substring(CryptoParametersJ8.CLEAR_CODE_DEFAULT.length()):
                 cipherText, password);
     }
 

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamGCMImpl.java Thu Jul 23 11:58:44 2020
@@ -69,24 +69,21 @@ public final class CryptoStreamGCMImpl e
      */
     public CryptoStreamGCMImpl() throws GeneralSecurityException
     {
-        this.salt =  generateSalt();
-        this.providerName = PROVIDERNAME;
-        this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_GCM.getAlgorithm();
+        this(generateSalt());
     }
 
 
     /**
      * Constructor
      *
-     * @param salt the salt for the PBE algorithm
-     * @param count the iteration for PBEParameterSpec
+     * @param salt the salt for the GCM algorithm
 
      */
-    public CryptoStreamGCMImpl( byte[] salt, int count) 
+    public CryptoStreamGCMImpl( byte[] salt) 
     {
-        this.salt = salt.clone();
-        this.count = count;
+        setSalt(salt);
         this.providerName = PROVIDERNAME;
+        setType(TYPES.GCM);
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_GCM.getAlgorithm();
     }
 
@@ -102,7 +99,6 @@ public final class CryptoStreamGCMImpl e
     protected Key createKey( char[] password, byte[] salt ) 
             throws GeneralSecurityException
     {
-
         SecretKey key = new SecretKeySpec(((salt == null)? this.getSalt(): salt.clone()), "AES");
         return key;
     }

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/algo/CryptoStreamPBEImpl.java Thu Jul 23 11:58:44 2020
@@ -31,7 +31,6 @@ import java.util.Arrays;
 
 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;
@@ -69,22 +68,35 @@ public final class CryptoStreamPBEImpl e
 
     protected static final int IV_SIZE = 16;
     
+    protected static final int KEY_SIZE = 256;
+    
 	/**
 	 * default count for pbe spec
 	 */
-	protected int COUNT_J8 = 10_000; // 200_000;
+	protected static final int COUNT_J8 = 10_000; // 200_000;
 
     /**
      * Constructor
+     * count is set to {@link #COUNT_J8}.
+     * 
      * @throws GeneralSecurityException  if no algo could be found.
      */
     public CryptoStreamPBEImpl() throws GeneralSecurityException
     {
-        this.salt =  generateSalt();
-        this.count = COUNT_J8;
-        this.providerName = PROVIDERNAME;
-        this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
+        this(generateSalt(), COUNT_J8);
+    }
+    
+    /**
+     * Constructor
+     *
+     * @param salt the salt for the PBE algorithm
+     */
+    public CryptoStreamPBEImpl( byte[] salt)
+    {
+        this(salt, COUNT_J8);
+        
     }
+
     
     /**
      * Constructor
@@ -94,9 +106,10 @@ public final class CryptoStreamPBEImpl e
      */
     public CryptoStreamPBEImpl( byte[] salt, int count)
     {
-        this.salt = salt.clone();
+        setSalt(salt);
         this.count = count;
         this.providerName = PROVIDERNAME;
+        setType(TYPES.PBE);
         this.algorithm = CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm();
     }
 

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/cli/CLI2.java Thu Jul 23 11:58:44 2020
@@ -27,6 +27,7 @@ import java.io.FileOutputStream;
 import java.io.OutputStreamWriter;
 import java.nio.charset.Charset;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -35,331 +36,336 @@ import java.util.stream.Collectors;
 import org.apache.fulcrum.jce.crypto.HexConverter;
 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;
 import org.apache.fulcrum.jce.crypto.extended.CryptoUtilJ8;
 
 /**
+ * <b>Manifest main class</b>.
+ * 
  * Command line tool for encrypting/decrypting a file or string
  *
- * file [enc|dec] passwd [file]*
- * string [enc|dec] passwd plaintext
+ * file [enc|dec] passwd [file]* string [enc|dec] passwd plaintext
  * 
  * Example :
  * 
- * <pre>java -classpath target/classes org.apache.fulcrum.jce.crypto.cli.CLI2 string enc changeit mysecretgeheim</pre>
+ * <pre>
+ * java -classpath target/classes org.apache.fulcrum.jce.crypto.cli.CLI2 string enc changeit mysecretgeheim
+ * </pre>
+ * 
+ * <pre>
+ * java -jar target/fulcrum-yaafi-crypto-1.0.8.jar string enc changeit mysecretgeheim
+ * </pre>
+ * 
  * ...
  * 
- * <pre>java -cp target/classes org.apache.fulcrum.jce.crypto.cli.Main string dec changeit J8_AES256 </pre>
+ * <pre>
+ * java java -jar target/fulcrum-yaafi-crypto-1.0.8.jar string dec changeit anothersecret
+ * </pre>
+ * 
+ *  @author gk@apache.org
  *
- * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
  */
-
-public class CLI2
-{
-    /**
-     * Allows usage on the command line.
-     * 
-     * @param args the command line parameters
-     */
-    public static void main( String[] args )
-    {
-        try
-        {
-            if (args.length ==0 ){
-                printHelp();
-                return;
-            }
-            String operationMode = args[0];
-            
-            String msg = "No operationMode" ;
-            if (operationMode == null || operationMode.equals("")) 
-            {
-                throw new IllegalArgumentException(msg);
-            }
-            
-            if( operationMode.equals("info") )
-            {
-                printInfo();
-                return;
-            } 
-            else if (operationMode.equals("help") ) 
-            {
-                printHelp();
-                return;
-            }
-            
-            if( args.length < 3 )
-            {
-                printHelp();
-                throw new IllegalArgumentException("Invalid command line");
-            }
-
-
-            if( operationMode.equals("file") )
-            {
-                processFiles(args);
-            }
-            else if( operationMode.equals("string") )
-            {
-                processString(args);
-            }
-        }
-        catch (Exception e)
-        {
-            System.out.println("Error : " + e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    private static void printInfo() 
-    {
-        CryptoUtilJ8 cryptoUtilJ8 = CryptoUtilJ8.getInstance();
-        System.out.println("\tCrypto factory class: " + cryptoUtilJ8.getCryptoStreamFactory().getClass());
-        System.out.println("\tDefault Algorithm used: " + cryptoUtilJ8.getCryptoStreamFactory().getAlgorithm());
-        String algoShortList= Arrays.stream(CryptoParametersJ8.TYPES.values()).map(t-> t.toString()).collect(Collectors.joining(","));
-        System.out.println("\tAlgorithms (shortcut) available: " + algoShortList);
-        String algoList= Arrays.stream(CryptoParametersJ8.TYPES_IMPL.values()).map(t-> t.toString()).collect(Collectors.joining(", "));
-        System.out.println("\tAlgorithms available: " + algoList);
-        System.out.println("\tMore Info: https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html");
-    }
-
-    /**
-     * Prints usage information.
-     */
-    public static void printHelp()
-    {
-        System.out.println("\r\n\t*** Command line tool for encrypting/decrypting strings/files ***\r\n\t*** algorithm based on "+ CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE+ "***\r\n");
-        System.out.println("\tjava -cp target\\classes; "+ CLI2.class.getName()+ " <operation mode> <coding mode> <password> <path|string> [target]\r\n");
-        System.out.println("\t\toperation mode: file|string|info");
-        System.out.println("\t\tcoding mode: enc|dec|enc:GCM. Default algorithm is " + TYPES.PBE);
-        System.out.println("\t\t<password: string or empty:''");
-        System.out.println("\t\tcode|coderef: path|string");
-        System.out.println("\t\ttarget: optional\r\n");
-        System.out.println( "\t*** Usage: ***\r\n");
-        System.out.println("\t\t"+ CLI2.class.getSimpleName()+ " file [enc|dec] passwd source [target]");
-        System.out.println("\t\t"+ CLI2.class.getSimpleName() + " string [enc|dec] passwd source");
-        System.out.println("\t\t"+ CLI2.class.getSimpleName() + " info");
-    }
-
-    /**
-     * Decrypt/encrypt a list of files
-     * @param args the command line
-     * @throws Exception the operation failed
-     */
-    public static void processFiles(String[] args)
-        throws Exception
-    {
-        String cipherMode = args[1];
-        char[] password = args[2].toCharArray();
-        File sourceFile = new File(args[3]);
-        File targetFile = null;
-
-        if (args.length == 4)
-        {
-            targetFile = sourceFile;
-        }
-        else
-        {
-            targetFile = new File(args[4]);
-            File parentFile = targetFile.getParentFile(); 
-
-            if (parentFile != null && (!parentFile.exists() || !parentFile.isDirectory()))
-            {
-                boolean success = parentFile.mkdirs();
-                if ( !success )
-                {
-                	System.err.println("Error, could not create directory to write parent file");
-                }            	
-            }
-        }
-
-        processFile(cipherMode,password,sourceFile,targetFile);
-    }
-
-    /**
-     * Decrypt/encrypt a single file
-     * @param cipherMode the mode
-     * @param password the password
-     * @param sourceFile the file to process
-     * @param targetFile the target file
-     * @throws Exception the operation failed
-     */
-    public static void processFile(String cipherMode, char[] password, File sourceFile, File targetFile)
-        throws Exception
-    {
-                
-        try (FileInputStream fis = new FileInputStream(sourceFile)) 
-        {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            CryptoUtilJ8 cryptoUtilJ8 = createCryptoUtil(cipherMode);
-    
-            if( cipherMode.startsWith("dec") )
-            {
-                System.out.println("Decrypting " + sourceFile.getAbsolutePath() );
-            
-                //String value = new String(Files.readAllBytes(Paths.get(sourceFile.toURI())));
-                StringBuffer stringBuffer = new StringBuffer();
-                int i; 
-                while ((i=fis.read()) != -1)  
-                {
-                    stringBuffer.append((char) i); 
-                } 
-                
-                String value = stringBuffer.toString();
-                if (isHexadecimal(value)) 
-                {
-                    byte[] buffer = HexConverter.toBytes(value);
-                    cryptoUtilJ8.decrypt( buffer, baos, password );
-                } 
-                else 
-                {
-                    try ( FileInputStream fis2 = new FileInputStream(sourceFile) ) 
-                    {
-                        cryptoUtilJ8.decrypt( fis2, baos, password );
-                    }
-                }
-    
-                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-                FileOutputStream fos = new FileOutputStream(targetFile);
-                StreamUtil.copy(bais,fos);
-                bais.close();
-                fos.close();
-            }
-            else if( cipherMode.startsWith("enc") )
-            {
-                System.out.println("Encrypting " + sourceFile.getAbsolutePath() );
-                cryptoUtilJ8.encrypt( fis, baos, password );
-                fis.close();
-    
-                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-                FileOutputStream fos = new FileOutputStream(targetFile);
-                StreamUtil.copy(bais,fos);
-                bais.close();
-                fos.close();
-            }
-            else
-            {
-                String msg = "Don't know what to do with : " + cipherMode;
-                throw new IllegalArgumentException(msg);
-            }
-        }
-    }
-
-    private static CryptoUtilJ8 createCryptoUtil(String cipherMode) throws Exception 
-    {
-        CryptoUtilJ8 cryptoUtilJ8 = null;
-        if (cipherMode.endsWith(TYPES.PBE.toString()) || cipherMode.substring("enc".length()).equals("") ) 
-        {
-            cryptoUtilJ8 = CryptoUtilJ8.getInstance();
-        } 
-        else 
-        {
-            Optional<TYPES> algoShortcut = Arrays.stream(CryptoParametersJ8.TYPES.values()).filter(a-> cipherMode.endsWith(a.toString())).findFirst(); //.collect(Collectors.toList());
-            if (algoShortcut.isPresent()) 
-            {
-                cryptoUtilJ8 = CryptoUtilJ8.getInstance(algoShortcut.get());
-            }
-        }
-        
-        if (cryptoUtilJ8 == null) 
-        {
-            throw new Exception("Could not find any algorithms. check provided alog shortcuts with CLI2 info!");
-        }
-        
-        return cryptoUtilJ8;
-    }
-
-    /**
-     * Decrypt and encrypt a string.
-     * 
-     * @param args the command line
-     * @throws Exception the operation failed
-     */
-    public static void processString(String[] args)
-        throws Exception
-    {
-        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]);
-            File parentFile = targetFile.getParentFile(); 
-
-            if (parentFile != null && (!parentFile.exists() || !parentFile.isDirectory()))
-            {
-                boolean success = parentFile.mkdirs();
-                if ( !success )
-                {
-                  System.err.println("Error, could not create directory to write parent file");
-                }
-                
-            }
-        }
-        
-        if (value != null && !value.equals("")) 
-        {
-
-            String result = processString(cipherMode, password, value);
-            
-            if (targetFile != null) {
-       
-              try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(targetFile), Charset.forName("UTF-8").newEncoder() ) )
-              {
-                osw.write(result);
-              }
-            } else {
-               System.out.println( result );
-            }
-        }
-    }
-    
-    /**
-     * Decrypt and encrypt a string.
-     * 
-     * @param cipherMode \"dec|enc\" + @link{TYPES}
-     * @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
-    {  
-        if (value != null && !value.equals("")) 
-        {
-            CryptoUtilJ8 cryptoUtilJ8 = createCryptoUtil(cipherMode);
-    
-            String result = null;
-            if ( cipherMode.startsWith("dec") )
-            {
-                result = cryptoUtilJ8.decryptString(value,password);
-            }
-            else if ( cipherMode.startsWith("enc"))
-            {
-                result = cryptoUtilJ8.encryptString(value,password);
-            }
-            return result;
-        } else {
-          return null;
-        }
-    }
-    
-    private static final Pattern HEXADECIMAL_PATTERN = Pattern.compile("\\p{XDigit}+");
-
-    public static boolean isHexadecimal(String input) {
-        final Matcher matcher = HEXADECIMAL_PATTERN.matcher(input);
-        return matcher.matches();
-    }
+public class CLI2 {
+	
+	
+	static boolean debug = false;
+	/**
+	 * Allows usage on the command line.
+	 * 
+	 * @param args the command line parameters
+	 */
+	public static void main(String[] args) {
+		try {
+			if (args.length == 0) {
+				printHelp();
+				return;
+			}
+			String operationMode = args[0];
+
+			String msg = "No operationMode";
+			if (operationMode == null || operationMode.equals("")) {
+				throw new IllegalArgumentException(msg);
+			}
+
+			if (operationMode.equals("info")) {
+				printInfo();
+				return;
+			} else if (operationMode.equals("help")) {
+				printHelp();
+				return;
+			}
+
+			if (args.length < 3) {
+				printHelp();
+				throw new IllegalArgumentException("Invalid command line");
+			}
+
+			if (operationMode.equals("file")) {
+				processFiles(args);
+			} else if (operationMode.equals("string")) {
+				processString(args);
+			}
+		} catch (Exception e) {
+			System.out.println("Error : " + e.getMessage());
+			e.printStackTrace();
+		}
+	}
+
+	private static void printInfo() {
+		CryptoUtilJ8 cryptoUtilJ8 = CryptoUtilJ8.getInstance();
+		System.out.println("");
+		System.out.println("\t|Crypto factory class: \t" + cryptoUtilJ8.getCryptoStreamFactory().getClass());
+		System.out.println("\t|_Default Algorithm used: \t" + cryptoUtilJ8.getCryptoStreamFactory().getAlgorithm());
+		List<String> algoShortList = Arrays.stream(CryptoParametersJ8.TYPES.values()).map(t -> t.toString())
+				.collect(Collectors.toList());
+		System.out.println("\t|Algorithms (shortcut) available: \t" + algoShortList);
+		String type = "AlgorithmParameters";
+		List result = CryptoParametersJ8.getSupportedAlgos(algoShortList, type, true);
+		System.out.println(
+				String.format("\t|_Matched supported %2$s:\t%1$s", 
+						((result.size() > 0) ? 
+								result:
+									CryptoParametersJ8.getSupportedAlgos(algoShortList, type, false)), type));
+	
+		List<String> algoList = Arrays.stream(CryptoParametersJ8.TYPES_IMPL.values()).map(t -> t.toString())
+				.collect(Collectors.toList());
+		System.out.println("\t|Algorithms available: \t" + algoList);
+		type = "Cipher";
+		result = CryptoParametersJ8.getSupportedAlgos(algoList, type, true);
+		System.out.println(
+				String.format("\t|_Matched Supported %2$ss:\t%1$s", 
+						((result.size() > 0) ? 
+								result:
+									CryptoParametersJ8.getSupportedAlgos(algoList, type, false)), type));
+		System.out.println("");
+		System.out.println(
+				"\t|_ More Info: https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html\r\n");
+	}
+	
+
+	/**
+	 * Prints usage information.
+	 */
+	public static void printHelp() {
+		System.out.println(
+				"\r\n\t*** Command line tool for encrypting/decrypting strings/files ***\r\n\t*** algorithm based on "
+						+ CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE + "***\r\n");
+		System.out.println("\tjava -cp target\\classes; " + CLI2.class.getName()
+				+ " <operation mode> <coding mode> <password> <path|string> [target]\r\n");
+		System.out.println(
+				"\tjava -jar target/fulcrum-yaafi-crypto-1.0.8-SNAPSHOT.jar <operation mode> <coding mode> <password> <path|string> [target]\r\n");
+		System.out.println("\t\t-------------------");
+		System.out.println("\t\toperation mode: file|string|info");
+		System.out.println("\t\tcoding mode: enc|dec|enc:GCM. Default algorithm is " + TYPES.PBE);
+		System.out.println("\t\t<password: string or empty:''");
+		System.out.println("\t\tcode|coderef: path|string");
+		System.out.println("\t\ttarget: optional\r\n");
+		System.out.println("\t\t-------------------");
+		System.out.println("\t*** Usage: ***\r\n");
+		System.out.println("\t\t" + CLI2.class.getSimpleName() + " file [enc|dec] passwd source [target]");
+		System.out.println("\t\t" + CLI2.class.getSimpleName() + " string [enc|dec] passwd source");
+		System.out.println("\t\t" + CLI2.class.getSimpleName() + " info");
+	}
+
+	/**
+	 * Decrypt/encrypt a list of files
+	 * 
+	 * @param args the command line
+	 * @throws Exception the operation failed
+	 */
+	public static void processFiles(String[] args) throws Exception {
+		String cipherMode = args[1];
+		char[] password = args[2].toCharArray();
+		File sourceFile = new File(args[3]);
+		File targetFile = null;
+
+		if (args.length == 4) {
+			targetFile = sourceFile;
+		} else {
+			targetFile = new File(args[4]);
+			File parentFile = targetFile.getParentFile();
+
+			if (parentFile != null && (!parentFile.exists() || !parentFile.isDirectory())) {
+				boolean success = parentFile.mkdirs();
+				if (!success) {
+					System.err.println("Error, could not create directory to write parent file");
+				}
+			}
+		}
+
+		processFile(cipherMode, password, sourceFile, targetFile);
+	}
+
+	/**
+	 * Decrypt/encrypt a single file
+	 * 
+	 * @param cipherMode the mode
+	 * @param password   the password
+	 * @param sourceFile the file to process
+	 * @param targetFile the target file
+	 * @throws Exception the operation failed
+	 */
+	public static void processFile(String cipherMode, char[] password, File sourceFile, File targetFile)
+			throws Exception {
+
+		try (FileInputStream fis = new FileInputStream(sourceFile)) {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			CryptoUtilJ8 cryptoUtilJ8 = createCryptoUtil(cipherMode);
+
+			if (cipherMode.startsWith("dec")) {
+				System.out.println("Decrypting " + sourceFile.getAbsolutePath());
+
+				// String value = new String(Files.readAllBytes(Paths.get(sourceFile.toURI())));
+				StringBuffer stringBuffer = new StringBuffer();
+				int i;
+				while ((i = fis.read()) != -1) {
+					stringBuffer.append((char) i);
+				}
+
+				String value = stringBuffer.toString();
+				if (isHexadecimal(value)) {
+					byte[] buffer = HexConverter.toBytes(value);
+					cryptoUtilJ8.decrypt(buffer, baos, password);
+				} else {
+					try (FileInputStream fis2 = new FileInputStream(sourceFile)) {
+						cryptoUtilJ8.decrypt(fis2, baos, password);
+					}
+				}
+
+				ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+				FileOutputStream fos = new FileOutputStream(targetFile);
+				StreamUtil.copy(bais, fos);
+				bais.close();
+				fos.close();
+			} else if (cipherMode.startsWith("enc")) {
+				System.out.println("Encrypting " + sourceFile.getAbsolutePath());
+				cryptoUtilJ8.encrypt(fis, baos, password);
+				fis.close();
+
+				ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+				FileOutputStream fos = new FileOutputStream(targetFile);
+				StreamUtil.copy(bais, fos);
+				bais.close();
+				fos.close();
+			} else {
+				String msg = "Don't know what to do with : " + cipherMode;
+				throw new IllegalArgumentException(msg);
+			}
+		}
+	}
+
+	private static CryptoUtilJ8 createCryptoUtil(String cipherMode) throws Exception {
+		CryptoUtilJ8 cryptoUtilJ8 = null;
+		// now extension like enc:GCM
+		if (cipherMode.endsWith(TYPES.PBE.toString()) || cipherMode.substring("enc".length()).equals("")) {
+			cryptoUtilJ8 = CryptoUtilJ8.getInstance();
+		} else {
+			List<String> supportedTypes = CryptoParametersJ8.init();
+			System.err.println("checking supported types:"+ supportedTypes);
+			List<String> matchedType = supportedTypes.stream().filter(x-> cipherMode.endsWith(x) ).collect(Collectors.toList());
+			System.err.println("matched type:"+ matchedType);
+			Optional<TYPES> algoShortcut = Arrays.stream(CryptoParametersJ8.TYPES.values())
+					.filter(a -> matchedType.get(0).equals(a.toString())).findFirst();
+			if (algoShortcut.isPresent()) {
+				System.err.println("initializing type:"+ algoShortcut);
+				cryptoUtilJ8 = CryptoUtilJ8.getInstance(algoShortcut.get());
+			}
+		}
+
+		if (cryptoUtilJ8 == null) {
+			throw new Exception("Could not find any algorithms. check provided algo shortcuts with CLI2 info!");
+		}
+		
+		if (debug) {
+			CryptoStreamFactoryJ8Template crt = ((CryptoStreamFactoryJ8Template)cryptoUtilJ8.getCryptoStreamFactory());
+			System.err.println(String.format("using crypto factory instance %s for algo %s and type %s with salt length: %s and count %s", 
+	           		crt.getClass().getSimpleName(), crt.getType(),
+	           		crt.getAlgorithm(), crt.getSalt().length, crt.getCount()));
+		}
+		return cryptoUtilJ8;
+	}
+
+	/**
+	 * Decrypt and encrypt a string.
+	 * 
+	 * @param args the command line
+	 * @throws Exception the operation failed
+	 */
+	public static void processString(String[] args) throws Exception {
+		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]);
+			File parentFile = targetFile.getParentFile();
+
+			if (parentFile != null && (!parentFile.exists() || !parentFile.isDirectory())) {
+				boolean success = parentFile.mkdirs();
+				if (!success) {
+					System.err.println("Error, could not create directory to write parent file");
+				}
+
+			}
+		}
+
+		if (value != null && !value.equals("")) {
+
+			String result = processString(cipherMode, password, value);
+
+			if (targetFile != null) {
+
+				try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(targetFile),
+						Charset.forName("UTF-8").newEncoder())) {
+					osw.write(result);
+				}
+			} else {
+				System.out.println(result);
+			}
+		}
+	}
+
+	/**
+	 * Decrypt and encrypt a string.
+	 * 
+	 * @param cipherMode \"dec|enc\" + @link{TYPES}
+	 * @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 {
+		if (value != null && !value.equals("")) {
+			CryptoUtilJ8 cryptoUtilJ8 = createCryptoUtil(cipherMode);
+
+			String result = null;
+			if (cipherMode.startsWith("dec")) {
+				result = cryptoUtilJ8.decryptString(value, password);
+			} else if (cipherMode.startsWith("enc")) {
+				result = cryptoUtilJ8.encryptString(value, password);
+			}
+			return result;
+		} else {
+			return null;
+		}
+	}
+
+	private static final Pattern HEXADECIMAL_PATTERN = Pattern.compile("\\p{XDigit}+");
+
+	public static boolean isHexadecimal(String input) {
+		final Matcher matcher = HEXADECIMAL_PATTERN.matcher(input);
+		return matcher.matches();
+	}
 }
\ No newline at end of file

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoParametersJ8.java Thu Jul 23 11:58:44 2020
@@ -1,5 +1,13 @@
 package org.apache.fulcrum.jce.crypto.extended;
 
+import java.security.Provider;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -26,7 +34,7 @@ package org.apache.fulcrum.jce.crypto.ex
  */
 
 public interface CryptoParametersJ8 {
-
+	
 	/**
 	 * 
 	 * Implementing classes are either using
@@ -42,14 +50,13 @@ public interface CryptoParametersJ8 {
 	 * </ul>
 	 * 
 	 * 
-	 * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJCEProvider">The Oracle Security SunJCE Provider</a>
+	 * <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">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>
+	 * Java 8: <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher">The Oracle Security Standard Names Cipher Algorithms</a>
 	 * 
+	 * Java 14: <a href="https://docs.oracle.com/en/java/javase/14/docs/specs/security/standard-names.html#security-algorithm-implementation-requirements">Security Algorithm Implementation Requirements</a>
 	 * 
 	 */
 	public enum TYPES_IMPL {
@@ -57,7 +64,7 @@ public interface CryptoParametersJ8 {
 		// key size 256
 		ALGORITHM_J8_PBE("PBEWithHmacSHA256AndAES_256"), 
 		// key size 128
-		ALGORITHM_J8_GCM("AES/GCM/NoPadding");
+		ALGORITHM_J8_GCM("AES_128/GCM/NoPadding");
 
 		private final String algorithm;
 
@@ -73,16 +80,113 @@ public interface CryptoParametersJ8 {
 		public String getAlgorithm() {
 			return algorithm;
 		}
+		
+		/**
+		 * clear code depending on algorithm AES size return <pre>J8AESAES_&lt;size&gt;;</pre>.
+		 * {@link CryptoParametersJ8#CLEAR_CODE_DEFAULT}
+		 *  
+		 * @return clear code J8AES_&lt;size&gt;; with three digit size.
+		 */
+		public String getClearCode() {
+			
+			return String.format("J8%1$s;", 
+					algorithm.subSequence(algorithm.indexOf("AES_"),algorithm.indexOf("AES_")+7));
+		}
 	}
 
+	/**
+	 * 
+	 * short names, exact names @see {@link TYPES_IMPL}.
+	 *
+	 */
 	public enum TYPES {
-		PBE, GCM
+		
+		/**
+		 *  PBE algorithm is kind of meta algorithm, uses AES, see above. 
+		 */
+		PBE, 
+		/**
+		 *  AES algorithm, but GCM is is actually the algorithm mode, but nevertheless used as a short name.
+		 */
+		GCM;
+
+		/**
+		 * Clear code should be always 10 bytes.
+		 * 
+		 * {@link CryptoParametersJ8#CLEAR_CODE_DEFAULT}
+		 * 
+		 * @return clear code
+		 * 
+		 */
+		public String getClearCode() {
+			return this.equals(TYPES.PBE)? 
+					TYPES_IMPL.ALGORITHM_J8_PBE.getClearCode():
+				TYPES_IMPL.ALGORITHM_J8_GCM.getClearCode();
+		}
 	}
 
 	/**
-	 * Prefix to decrypted hex hash to get a clue, what to use and what it is.
+	 * Prefix to decrypted hex hash to get a clue, what to use and what it is; should be always 10 bytes.
+	 */
+	public String CLEAR_CODE_DEFAULT = "J8_AES064;";
+	
+	public TYPES DEFAULT_TYPE = TYPES.PBE;
+
+	
+	/**
+	 * Checks Java provider with <b>type</b> has exact type or contains any of the strings in algoList.
+	 * <pre>Types</pre> may be Cipher, AlgorithmParameters, KeyGenerator, Alg, Mac, SecretKeyFactory.
+	 * 
+	 * @param algoList the types to be checked
+	 * @param type the type is ignored if not exact, instead uses the two types: "AlgorithmParameters", "Cipher".
+	 * @param exact if exact does a exact match 
+	 * @return the matched results as a list
+	 */
+	public static List<String> getSupportedAlgos(List<String> algoList, String type, boolean exact) {
+		List<String> result = new ArrayList<String>();
+		Provider p[] = Security.getProviders();
+		List<Provider> providerList = Arrays.asList(p);
+
+		String[] PROVIDER_TYPES = { "AlgorithmParameters", "Cipher" };
+		for (Provider provider : providerList) {
+			// System.out.println(provider);
+			result.addAll(Collections.list(provider.keys()).stream().map(t -> t.toString())
+					.filter(x->
+							(exact)? 
+							(x.startsWith(type) && algoList.contains(x.replaceAll(type + ".", ""))):
+							(x.matches("(" +String.join("|", PROVIDER_TYPES) + ").*$") && 
+									algoList.stream().anyMatch(y -> y.contains(x.replaceAll(type + ".", "")))
+							)
+					)
+					.map( x ->
+					(exact)? 
+					   x.replaceAll(type + ".", ""):
+						   x.replaceAll("(" +String.join("|", PROVIDER_TYPES) + ")" + ".", "")
+					)
+					.collect(Collectors.toList()));
+		}
+		return result;
+	}
+
+	/**
+	 * initializes supported parameters by filtering {@link TYPES} against <i>AlgorithmParameters</i> in system supported cipher suites:
+	 * first by an exact match with type <i>AlgorithmParameters</i>, then by inexact matching.
 	 * 
-	 * This should be always 10 bytes
+	 * {@link #getSupportedAlgos(List, String, boolean)}
+	 * @return list of supported algo short codes, if nothing is found the {@link #DEFAULT_TYPE} is set.
 	 */
-	String CLEAR_CODE_J8 = "J8_AES256;";
+	static List<String> init() {
+		List<String> result = new ArrayList<String>();
+		List<String> defaultSupportedTypes = Arrays.asList( TYPES.values() ).stream().map(x-> x.toString()).collect(Collectors.toList());
+		String providerType = "AlgorithmParameters";
+		result = getSupportedAlgos(defaultSupportedTypes, providerType, true);
+		if (result.isEmpty()) {
+			// minimal default, try it 
+			result = getSupportedAlgos(defaultSupportedTypes, providerType, false);
+			result = !result.isEmpty()? 
+					result: Arrays.asList( DEFAULT_TYPE).stream().map(x-> x.toString()).collect(Collectors.toList());
+		} 
+		return result;
+	}
+
 }

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoStreamFactoryJ8Template.java Thu Jul 23 11:58:44 2020
@@ -23,7 +23,6 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.security.AlgorithmParameters;
 import java.security.GeneralSecurityException;
 import java.security.Key;
 import java.security.NoSuchAlgorithmException;
@@ -50,7 +49,7 @@ public abstract class CryptoStreamFactor
 	/** the salt for the algorithm */
     protected byte[] salt;
 
-    /** the count paramter for the algorithm */
+    /** the count parameter for the algorithm, not used for GCM */
     protected int count;
 
     /** the name of the JCE provider */
@@ -59,6 +58,16 @@ public abstract class CryptoStreamFactor
     /** the algorithm to use */
     protected String algorithm;
     
+    private TYPES type;
+    
+    public TYPES getType() {
+      return type;
+    }
+    
+    public void setType(TYPES type) {
+    	this.type = type;
+    }
+    
     /**
      * The JCE provider name known to work. If the value
      * is set to null an appropriate provider will be
@@ -67,16 +76,42 @@ public abstract class CryptoStreamFactor
     protected static final String PROVIDERNAME = null;
 
     protected static final int SALT_SIZE = 16; //might increase cipher length
-    protected static final int KEY_SIZE = 256;
 
     /** the default instances */
-    protected static Map<TYPES,CryptoStreamFactoryJ8Template> instances = new ConcurrentHashMap<>();
+    protected static final Map<TYPES,CryptoStreamFactoryJ8Template> instances = new ConcurrentHashMap<>();
     
     //protected AlgorithmParameters algorithmParameters;// used only for debugging
    
     public CryptoStreamFactoryJ8Template() {
        
     }
+    
+    /**
+     * Factory method to get a default instance
+     * 
+     * creating instance of type {@link CryptoParametersJ8#DEFAULT_TYPE}.
+     * 
+     * @return an instance of the CryptoStreamFactory
+     */
+    public static CryptoStreamFactoryJ8 getInstance() 
+    {
+        synchronized (CryptoStreamFactoryJ8Template.class) {
+            if( !instances.containsKey(CryptoParametersJ8.DEFAULT_TYPE) )
+            {
+                try {
+                    instances.put(CryptoParametersJ8.DEFAULT_TYPE, 
+                            (CryptoParametersJ8.DEFAULT_TYPE.equals(TYPES.PBE))? new CryptoStreamPBEImpl():
+                                new CryptoStreamGCMImpl()
+                            );
+                } catch (GeneralSecurityException e) {
+                    e.printStackTrace();
+                    throw new RuntimeException(e.getMessage());
+                }
+            }
+    
+            return instances.get(CryptoParametersJ8.DEFAULT_TYPE);
+        }
+    }
 
     /**
      * Factory method to get a default instance
@@ -103,22 +138,33 @@ public abstract class CryptoStreamFactor
             return instances.get(type);
         }
     }
-
-
+    
     /**
-     * Constructor
-     *
-     * @param salt the salt for the PBE algorithm
-     * @param count the iteration for PBEParameterSpec
-     * @param type {@link TYPES} what type the algorithm will be
-     */
-    public CryptoStreamFactoryJ8Template( byte[] salt, int count, TYPES type)
-    {
-        this.salt = salt.clone();
-        this.count = count;
-        this.providerName = PROVIDERNAME;
-        this.algorithm = type.equals(TYPES.PBE)? CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_PBE.getAlgorithm():
-            CryptoParametersJ8.TYPES_IMPL.ALGORITHM_J8_GCM.getAlgorithm();;
+     * Factory method to get a default instance
+     * 
+     * @param type the @see {@link TYPES} of the instance.
+     * @param salt provided salt
+     * @param count provided count, used only for {@link TYPES#PBE}.
+     * @return an instance of the CryptoStreamFactory
+     */
+    public static CryptoStreamFactoryJ8 getInstance(TYPES type, byte[] salt, int count) 
+    {
+        synchronized (CryptoStreamFactoryJ8Template.class) {
+            if( !instances.containsKey(type) )
+            {
+                try {
+                    instances.put(type, 
+                            (type.equals(TYPES.PBE))? new CryptoStreamPBEImpl(salt, count):
+                                new CryptoStreamGCMImpl(salt)
+                            );
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new RuntimeException(e.getMessage());
+                }
+            }
+    
+            return instances.get(type);
+        }
     }
 
 
@@ -146,6 +192,9 @@ public abstract class CryptoStreamFactor
         return eis;
     }
 
+    /**
+     * @see org.apache.fulcrum.jce.crypto.extended.CryptoStreamFactoryJ8#getOutputStream(InputStream, OutputStream, char[])
+     */
     public OutputStream getOutputStream(InputStream is, OutputStream os, char[] password)
             throws GeneralSecurityException, IOException {
         byte[] encrypted =  this.createCipher( is, Cipher.ENCRYPT_MODE, password.clone() );
@@ -162,16 +211,16 @@ public abstract class CryptoStreamFactor
         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;
-    }
+//    /**
+//     * 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 **/
     
@@ -239,12 +288,12 @@ public abstract class CryptoStreamFactor
      * 
      * 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}.
+     * salt size is 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 {
+    protected static byte[] generateSalt() throws GeneralSecurityException {
         SecureRandom random;
         try {
             random = SecureRandom.getInstanceStrong();
@@ -260,7 +309,7 @@ public abstract class CryptoStreamFactor
 		return salt.clone();
 	}
 
-	public void setSalt(byte[] salt) {
+	protected void setSalt(byte[] salt) {
 		this.salt = salt.clone();
 	}
 

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/java/org/apache/fulcrum/jce/crypto/extended/CryptoUtilJ8.java Thu Jul 23 11:58:44 2020
@@ -32,27 +32,36 @@ import org.apache.fulcrum.jce.crypto.Str
 import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8.TYPES;
 
 /**
- * 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/
+ * Helper class to provide typed functions to work with CryptoStreams.
  *
  * @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 {
 
-	/** the typed default instances */
-	private static Map<TYPES, CryptoUtilJ8> cryptoUtilJ8s = new ConcurrentHashMap<>();
-
-	// default see instance
-	public TYPES type;
-
-	public TYPES getType() {
-		return type;
+	/** the typed default instances */   
+    private static final Map<TYPES, CryptoUtilJ8> instances = new ConcurrentHashMap<>();
+    
+    /** the default instances with custom settings **/
+    private static final Map<TYPES, CryptoUtilJ8> instancesWithExplicitParams = new ConcurrentHashMap<>();    
+	
+	/**
+	 * 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 = CryptoParametersJ8.DEFAULT_TYPE;
+			if (instances.isEmpty() && !instances.containsKey(defaultType)) {
+				instances.put(defaultType, new CryptoUtilJ8());
+			}
+			return instances.get(defaultType);
+		}
 	}
-
+	
 	/**
 	 * Factory method to get a default instance
 	 * 
@@ -61,42 +70,53 @@ public final class CryptoUtilJ8 extends
 	 */
 	public static CryptoUtilJ8 getInstance(TYPES type) {
 		synchronized (CryptoUtilJ8.class) {
-			if (!cryptoUtilJ8s.containsKey(type)) {
-				cryptoUtilJ8s.put(type, new CryptoUtilJ8(type));
+			if (!instances.containsKey(type)) {
+				instances.put(type, new CryptoUtilJ8(type));
 			}
-			return cryptoUtilJ8s.get(type);
+			return instances.get(type);
 		}
 	}
-
+	
 	/**
 	 * Factory method to get a default instance
 	 * 
-	 * default type PDC
-	 * 
+	 * @param type one of the enum {@link TYPES}.
+	 * @param salt the salt
+	 * @param count the iteration count
 	 * @return an instance of the CryptoStreamFactory
 	 */
-	public static CryptoUtilJ8 getInstance() {
+	public static CryptoUtilJ8 getInstance(TYPES type, byte[] salt, int count) {
 		synchronized (CryptoUtilJ8.class) {
-			TYPES defaultType = TYPES.PBE;
-			if (cryptoUtilJ8s.isEmpty() && !cryptoUtilJ8s.containsKey(defaultType)) {
-				cryptoUtilJ8s.put(defaultType, new CryptoUtilJ8(defaultType));
+			if (!instancesWithExplicitParams.containsKey(type)) {
+				instancesWithExplicitParams.put(type, new CryptoUtilJ8(type, salt, count));
 			}
-			return cryptoUtilJ8s.get(defaultType);
+			return instancesWithExplicitParams.get(type);
 		}
 	}
-
-	private CryptoUtilJ8(TYPES type) {
-		super();
-		this.type = type;
-	}
-
+	
 	private CryptoUtilJ8() {
-		super();
+		cryptoStreamFactory = CryptoStreamFactoryJ8Template.getInstance();
+	}
+	
+	private CryptoUtilJ8(TYPES type) {
+		cryptoStreamFactory = CryptoStreamFactoryJ8Template.getInstance(type);
 	}
+	
+    /**
+     * 
+     * @param type one of the enum {@link TYPES}.
+     * @param salt v
+     * @param count the iteration count
+     */
+    protected CryptoUtilJ8(TYPES type, byte[] salt, int count) {
+    	cryptoStreamFactory = CryptoStreamFactoryJ8Template.getInstance(type, salt, count);
+    }
 
 	/**
 	 * Copies from a source to a target object using encryption and a caller
 	 * supplied CryptoStreamFactory.
+	 * 
+	 * {@link CryptoStreamFactoryJ8Template#getOutputStream(InputStream, OutputStream, char[])} 
 	 *
 	 * @param factory  the factory to create the crypto streams
 	 * @param source   the source object
@@ -110,8 +130,7 @@ public final class CryptoUtilJ8 extends
 			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 );
+		((CryptoStreamFactoryJ8) factory).getOutputStream(is, os, password);
 	}
 
 	/**
@@ -134,11 +153,12 @@ public final class CryptoUtilJ8 extends
 		StreamUtil.copy(dis, os);
 	}
 
-	/**
-	 * 
-	 * @return the CryptoStreamFactory to be used
-	 */
-	public CryptoStreamFactory getCryptoStreamFactory() {
-		return CryptoStreamFactoryJ8Template.getInstance(type);
+	public static Map<TYPES, CryptoUtilJ8> getInstances() {
+		return instances;
+	}
+
+	public static Map<TYPES, CryptoUtilJ8> getInstancesWithExplicitParams() {
+		return instancesWithExplicitParams;
 	}
+
 }

Modified: turbine/fulcrum/trunk/yaafi-crypto/src/test/log4j2.xml
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/test/log4j2.xml?rev=1880199&r1=1880198&r2=1880199&view=diff
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/test/log4j2.xml (original)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/test/log4j2.xml Thu Jul 23 11:58:44 2020
@@ -1,58 +1,55 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
+<!-- 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. -->
 <Configuration status="info" verbose="false">
-    <Appenders>
-      <Console name="console" target="SYSTEM_OUT">
-          <PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
-	    </Console>
-	    <File name="logfile" fileName="target/fulcrum-test.log">
-          <PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
-	    </File>
-	    <File name="avalon" fileName="target/avalon-test.log">
-          <PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
-	    </File>
-    </Appenders>
-    <Loggers>
-      <Logger name="org.apache.fulcrum.jce.crypto" level="debug" additivity="false">
-            <AppenderRef ref="console"/>
-            <AppenderRef ref="logfile"/>
-       </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"/>
-      </Logger>
-       <Logger name="org.apache.fulcrum.yaafi" level="info" additivity="false">
-          <AppenderRef ref="avalon"/>
-      </Logger>
-      <Logger name="avalon" level="warn" additivity="false">
-          <AppenderRef ref="avalon"/>
-      </Logger>
-      <Logger name="org.apache.logging.log4j" level="warn" additivity="false">
-          <AppenderRef ref="logfile"/>
-      </Logger>
-      <Root level="error">
-          <AppenderRef ref="console"/>
-      </Root>
-    </Loggers>
+  <Appenders>
+    <Console name="console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d [%t] %-5p %c - %m%n" />
+    </Console>
+    <File name="logfile" fileName="target/fulcrum-test.log">
+      <PatternLayout pattern="%d [%t] %-5p %c - %m%n" />
+    </File>
+    <File name="avalon" fileName="target/avalon-test.log">
+      <PatternLayout pattern="%d [%t] %-5p %c - %m%n" />
+    </File>
+  </Appenders>
+  <Loggers>
+    <Logger name="org.apache.fulcrum.jce.crypto" level="debug"
+      additivity="false">
+      <AppenderRef ref="console" />
+      <AppenderRef ref="logfile" />
+    </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" />
+    </Logger>
+    <Logger name="org.apache.fulcrum.yaafi" level="info"
+      additivity="false">
+      <AppenderRef ref="avalon" />
+    </Logger>
+    <Logger name="avalon" level="warn" additivity="false">
+      <AppenderRef ref="avalon" />
+    </Logger>
+    <Logger name="org.apache.logging.log4j" level="warn"
+      additivity="false">
+      <AppenderRef ref="logfile" />
+    </Logger>
+    <Root level="error">
+      <AppenderRef ref="console" />
+    </Root>
+  </Loggers>
 </Configuration>
\ No newline at end of file

Added: turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilExplicitParamsTest.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilExplicitParamsTest.java?rev=1880199&view=auto
==============================================================================
--- turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilExplicitParamsTest.java (added)
+++ turbine/fulcrum/trunk/yaafi-crypto/src/test/org/apache/fulcrum/jce/crypto/CryptoUtilExplicitParamsTest.java Thu Jul 23 11:58:44 2020
@@ -0,0 +1,447 @@
+package org.apache.fulcrum.jce.crypto;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import org.apache.fulcrum.jce.crypto.extended.CryptoParametersJ8;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test suite for crypto functionality
+ *
+ * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
+ */
+
+public class CryptoUtilExplicitParamsTest {
+	/** the password to be used */
+	private String password;
+
+	/** the test data directory */
+	private File testDataDirectory;
+
+	/** the temp data director */
+	private File tempDataDirectory;
+	
+	private static Logger log = LogManager.getLogger(CryptoUtilExplicitParamsTest.class);
+	
+	private static byte[] SALT = Salt();
+	
+	private static int COUNT = 25;
+	
+	 public static byte[] Salt()
+	 {
+		SecureRandom random;
+		try {
+			random = SecureRandom.getInstanceStrong();
+	        byte[] salt = new byte[ 8 ];
+	        random.nextBytes(salt);
+	        return salt;
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		}
+		return null;
+	 }
+
+	/**
+	 * Constructor
+	 */
+	public CryptoUtilExplicitParamsTest() {
+		this.password = "mysecret";
+		this.testDataDirectory = new File("./src/test/data");
+		this.tempDataDirectory = new File("./target/temp");
+		this.tempDataDirectory.mkdirs();
+	}
+
+	/**
+	 * 
+	 * @throws Exception Generic exception
+	 */
+	@BeforeAll
+	protected static void setUp() throws Exception {
+	}
+
+	/**
+	 * @return Returns the password.
+	 */
+	protected char[] getPassword() {
+		return password.toCharArray();
+	}
+
+	/**
+	 * @return Returns the tempDataDirectory.
+	 */
+	protected File getTempDataDirectory() {
+		return tempDataDirectory;
+	}
+
+	/**
+	 * @return Returns the testDataDirectory.
+	 */
+	protected File getTestDataDirectory() {
+		return testDataDirectory;
+	}
+
+	/** Encrypt a text file 
+	 */
+	@Test
+	public void testTextEncryption()  {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain.txt");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.enc.txt");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException e) {
+			fail(e);
+		} catch (IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Decrypt a text file 
+	 */
+	@Test
+	public void testTextDecryption()  {
+		testTextEncryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain.enc.txt");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.dec.txt");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile.getAbsolutePath(), this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Encrypt an empty text file 
+	 */
+	@Test
+	public void testEmptyTextEncryption() {
+		File sourceFile = new File(this.getTestDataDirectory(), "empty.txt");
+		File targetFile = new File(this.getTempDataDirectory(), "empty.enc.txt");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Decrypt a text file
+	 */
+	@Test
+	public void testEmptyTextDecryption() {
+		testEmptyTextEncryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "empty.enc.txt");
+		File targetFile = new File(this.getTempDataDirectory(), "empty.dec.txt");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Encrypt a PDF file 
+	 */
+	@Test
+	public void testPdfEncryption()  {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain.pdf");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.enc.pdf");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Decrypt a PDF file 
+	 */
+	@Test
+	public void testPdfDecryption() {
+		testPdfEncryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain.enc.pdf");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.dec.pdf");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Encrypt a ZIP file 
+	 */
+	@Test
+	public void testZipEncryption()  {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain.zip");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.enc.zip");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Decrypt a ZIP file 
+	 */
+	@Test
+	public void testZipDecryption()  {
+		testZipEncryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain.enc.zip");
+		File targetFile = new File(this.getTempDataDirectory(), "plain.dec.zip");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Encrypt a UTF-16 XML file 
+	 */
+	@Test
+	public void testXmlUTF16Encryption()  {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain-utf16.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-utf16.enc.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/**
+	 * Decrypt a UTF-16 XML file
+	 */
+	 @Test
+	public void testXMLUTF16Decryption() {
+		testXmlUTF16Encryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain-utf16.enc.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-utf16.dec.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/**
+	 * Encrypt a UTF-8 XML file
+	 */
+	 @Test
+	public void testXmlUTF8Encryption() {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain-utf8.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-utf8.enc.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/**
+	 * Decrypt a UTF-8 XML file
+	 */
+	 @Test
+	public void testXMLUTF8Decryption() {
+		testXmlUTF8Encryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain-utf8.enc.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-utf8.dec.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/**
+	 * Encrypt a ISO-8859-1 XML file
+	 */
+	@Test
+	public void testXmlISO88591Encryption()  {
+		File sourceFile = new File(this.getTestDataDirectory(), "plain-iso-8859-1.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-iso-8859-1.enc.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).encrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/**
+	 * Decrypt a ISO-8859-1 XML file
+	 */
+	@Test
+	public void testXmlISO88591Decryption()  {
+		testXmlISO88591Encryption();
+		File sourceFile = new File(this.getTempDataDirectory(), "plain-iso-8859-1.enc.xml");
+		File targetFile = new File(this.getTempDataDirectory(), "plain-iso-8859-1.dec.xml");
+		try {
+			CryptoUtil.getInstance(SALT,COUNT).decrypt(sourceFile, targetFile, this.getPassword());
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+	}
+
+	/** Test encryption and decryption of Strings
+	 */
+	@Test
+	public void testStringEncryption()  {
+		char[] testVector = new char[513];
+
+		for (int i = 0; i < testVector.length; i++) {
+			testVector[i] = (char) i;
+		}
+
+		String source = new String(testVector);
+		try {
+			String cipherText = CryptoUtil.getInstance(SALT,COUNT).encryptString(source, this.getPassword());
+			String plainText = CryptoUtil.getInstance(SALT,COUNT).decryptString(cipherText, this.getPassword());
+			assertEquals(source, plainText);
+		} catch (GeneralSecurityException | IOException e) {
+			fail(e);
+		}
+		
+	}
+	
+	@Test
+	public void testStringEncryptionWithType() {
+		CryptoUtil cu = CryptoUtil.getInstance(SALT,COUNT);
+		char[] testVector = new char[513];
+
+		for (int i = 0; i < testVector.length; i++) {
+			testVector[i] = (char) i;
+		}
+
+		String source = new String(testVector);
+		String cipherText = null;
+		String plainText = null;
+		try {
+			log.info("Test without clearTextHeader");
+			cipherText = cu.encryptString(source, this.getPassword());
+			log.trace(cipherText);
+			plainText = cu.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_DEFAULT));
+			String cipherText2 = cu.encryptStringWithClearCode(source, this.getPassword());
+			log.trace(cipherText2);
+			// old style
+			assertTrue(cipherText2.startsWith(CryptoParametersJ8.CLEAR_CODE_DEFAULT),
+					String.format("%s does not start with '%s'", cipherText2, CryptoParametersJ8.CLEAR_CODE_DEFAULT));
+			String plainText2 = cu.decryptStringWithClearCode(cipherText2, this.getPassword());
+			assertEquals(source, plainText2, String.format("%s is not equal with %s", source, plainText));
+
+		} catch (GeneralSecurityException | IOException e) {
+			e.printStackTrace();
+			fail();
+		}
+	}
+
+	/** Test encryption and decryption of Strings
+	 */
+	@Test
+	public void testStringHandling() {
+		String source = "Nobody knows the toubles I have seen ...";
+		try {
+			String cipherText = CryptoUtil.getInstance(SALT,COUNT).encryptString(source, this.getPassword());
+			String plainText = CryptoUtil.getInstance(SALT,COUNT).decryptString(cipherText, this.getPassword());
+		assertEquals(source, plainText);
+		} catch (GeneralSecurityException | IOException e) {
+			e.printStackTrace();
+			fail();
+		}
+	}
+
+	/** Test encryption and decryption of binary data
+	 * @throws Exception Generic exception
+	 */
+	 @Test
+	public void testBinaryHandling() throws Exception {
+		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();
+
+		CryptoUtil.getInstance(SALT,COUNT).encrypt(source, cipherText, this.getPassword());
+		CryptoUtil.getInstance(SALT,COUNT).decrypt(cipherText, plainText, this.getPassword());
+
+		result = plainText.toByteArray();
+
+		for (int i = 0; i < source.length; i++) {
+			if (source[i] != result[i]) {
+				fail("Binary data are different at position " + i);
+			}
+		}
+	}
+
+	/** Test creating a password
+	 * @throws Exception Generic exception
+	 */
+	@Test
+	public void testPasswordFactory() throws Exception {
+		char[] result = null;
+		result = PasswordFactory.getInstance().create();
+		System.out.println(new String(result));
+		result = PasswordFactory.getInstance().create(this.getPassword());
+		log.info(new String(result));
+		assertNotNull(result);
+	}
+
+	/** Test the hex converter
+	 * @throws Exception Generic exception
+	 */
+	 @Test
+	public void testHexConverter() throws Exception {
+		String source = "DceuATAABWSaVTSIK";
+		String hexString = HexConverter.toString(source.getBytes());
+		String result = new String(HexConverter.toBytes(hexString));
+		assertEquals(source, result);
+	}
+
+	/** Test encryption and decryption of Strings 
+	 * @throws Exception Generic exception
+	 */
+	 @Test
+	public void testPasswordEncryption() throws Exception {
+		char[] password = "57cb-4a23-d838-45222".toCharArray();
+		String source = "e02c-3b76-ff1e-5d9a1";
+		String cipherText = CryptoUtil.getInstance(SALT,COUNT).encryptString(source, password);
+		log.info(cipherText);// len 48
+		assertEquals(48, cipherText.length());
+		String plainText = CryptoUtil.getInstance(SALT,COUNT).decryptString(cipherText, password);
+		assertEquals(source, plainText);
+	}
+
+}