Encrypt tomcat keystore password

前端 未结 6 972
北海茫月
北海茫月 2020-12-25 08:44

Is there an option to encrypt keystorePass value in tomcat server.xml? I don\'t want it to be a plain text

    

        
6条回答
  •  我在风中等你
    2020-12-25 09:06

    We were also facing similar problem but we created our own encryption and decryption logic to tackle this. Here is the code

    /* class is used to generate encrypted password */
    
    public class ClientForPasswordGeneration {
    
        public static void main(String[] args) {
            //final String secretKey = "ssshhhhhhhhhhh!!!!";
            final String secretKey = PasswordKey.getEncryptionKey();
            GenerateLogic object = new GenerateLogic();
    
            String password = PasswordField.readPassword("Enter password: ");
    
            String encryptPassword = object.encrypt(password, secretKey);
            System.out.println("Encrypted Password:");
            System.out.println(encryptPassword);
    
        }
    
    }
    

    Another Class

    class EraserThread implements Runnable {
        private boolean stop;
    
        /**
         * @param The
         *            prompt displayed to the user
         */
        public EraserThread(String prompt) {
            System.out.print(prompt);
        }
    
        /**
         * Begin masking...display asterisks (*)
         */
        public void run() {
            stop = true;
            while (stop) {
    
                System.out.print("\010*");
    
                try {
    
                    Thread.currentThread().sleep(1);
                    // System.out.println("current thread::" + Thread.currentThread());
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        }
    
        /**
         * Instruct the thread to stop masking
         */
        public void stopMasking() {
            this.stop = false;
        }
    
    }
    

    Logic which generated hashed code

    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Arrays;
    import java.util.Base64;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    
    public class GenerateLogic {
        private static SecretKeySpec secretKey;
        private static byte[] key;
    
        public static void setKey(String myKey) {
            MessageDigest sha = null;
            try {
                key = myKey.getBytes("UTF-8");
                sha = MessageDigest.getInstance("SHA-1");
                key = sha.digest(key);
                key = Arrays.copyOf(key, 16);
                secretKey = new SecretKeySpec(key, "AES");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    
        public static String encrypt(String strToEncrypt, String secret) {
            try {
                setKey(secret);
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
            } catch (Exception e) {
                System.out.println("Error while encrypting: " + e.toString());
            }
            return null;
        }
    
        public static String decrypt(String strToDecrypt) {
            try {
                //System.out.println("decryptedString methods");
                //String secret = "ssshhhhhhhhhhh!!!!";
                String secret = PasswordKey.getEncryptionKey();
                setKey(secret);
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
                cipher.init(Cipher.DECRYPT_MODE, secretKey);
                //System.out.println("testing string values::" + new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))));
                return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
            } catch (Exception e) {
                System.out.println("Error while decrypting: " + e.toString());
            }
            return null;
        }
    
        public static void main(String[] args) {
            final String secretKey = "ssshhhhhhhhhhh!!!!";
    
            String originalString = "changeit";
            String encryptedString = GenerateLogic.encrypt(originalString, secretKey);
            String decryptedString = GenerateLogic.decrypt(encryptedString);
    
            System.out.println(originalString);
            System.out.println(encryptedString);
            System.out.println(decryptedString);
        }
    
    }
    

    This is where we extended the class org.apache.coyote.http11.Http11Nio2Protocol which is present in tomcat-coyote-8.0.29.jar which is present in lib folder of tomcat 8. So while compiling these classes tomcat-coyote-8.0.29.jar should be present.

    public class Http11Nio2Protocol extends org.apache.coyote.http11.Http11Nio2Protocol {
    
        @Override
        public void setKeystorePass(String s) {
            try {
                super.setKeystorePass(new GenerateLogic().decrypt(s));
            } catch (final Exception e) {
                super.setKeystorePass("");
            }
        }
    
    }
    

    This is where user has to enter password in cmd which should be hashed

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class PasswordField {
    
        /**
         * @param prompt
         *            The prompt to display to the user
         * @return The password as entered by the user
         */
        public static String readPassword(String prompt) {
            EraserThread et = new EraserThread(prompt);
            Thread mask = new Thread(et);
            mask.start();
    
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String password = "";
    
            try {
                password = in.readLine();
    
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
            // stop masking
            et.stopMasking();
            // return the password entered by the user
            return password;
        }
    }
    

    This is where you keep your password key. You should change it.

    public class PasswordKey {
    
        private static String ENCRYPTION_KEY = "myKeysecretkey";
    
        protected static String getEncryptionKey()
        {
            return ENCRYPTION_KEY;
        }
    
    }
    

    compile above classes to generate class files with below command in cmd. Remember tomcat-coyote-8.0.29.jar should be present in same folder where all the java files are present.

    javac  -cp ".;tomcat-coyote-8.0.29.jar" *.java
    

    Make a jar with the generated class file using this command in cmd

    jar -cvf  PasswordEncryptor.jar  *.class
    

    This will create a jar file PasswordEncryptor.jar

    Paste the generated PasswordEncryptor.jar in lib folder of Tomcat8. i.e. apache-tomcat-8.5.9\lib

    Now go to this location and type below command to generate the hashed password.

    java -cp ".;PasswordEncryptor.jar" ClientForPasswordGeneration
    

    Now go to apache-tomcat-8.5.9\conf and edit server.xml

    Use the hashed password in keystorpasss of certificate

    
    

    Notice the protocol is the custom class name.

    Hope this will help you.

    Thanks

提交回复
热议问题