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 [email protected]
  *
- * @author <a href="mailto:[email protected]";>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:[email protected]";>Siegfried Goeschl </a>
- * @author <a href="mailto:[email protected]";>Markus Hahn</a>
  * @author <a href="mailto:[email protected]";>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:[email protected]";>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);
+       }
+
+}


Reply via email to