-->

tomcat的加密存储密码(Encrypt tomcat keystore password)

2019-09-01 01:52发布

有没有在tomcat的server.xml中加密keystorePass值的选项? 我不希望它是一个纯文本

    <Connector port="8403" //...
        keystorePass="myPassword" /> 

Answer 1:

如果有人访问你的server.xml中,出现在您的keystorePass的纯文本值只是你的担忧之一。

如果有人从那里访问,他们可以做更多的伤害。 这里加密密码真的只是移动的问题在其他地方,然后有人能找到这个加密密钥(有点像俄罗斯套娃)的加密密钥。

如果要加密的密码,您必须覆盖连接器执行解密加密的密码,这样,真正的PWD是访问或可用到Tomcat。



Answer 2:

有一个更好的办法,比只使用XML编码。

创建加密类来加密和解密密码。

并重写Http11Nio2Protocol类,类似于下面的代码的东西。

 public class Http11Nio2Protocol extends org.apache.coyote.http11.Http11Nio2Protocol {

@Override
public void setKeystorePass(String s) {
    try {
        super.setKeystorePass(new EncryptService().decrypt(s));
    } catch (final Exception e){
        super.setKeystorePass("");
    }
}

}

:EncryptService是我们自己的加密类。

并配置在协议属性被覆盖的类server.xml中像下面。

<Connector port="8443" protocol="<com.mypackage.overridden_Http11Nio2Protocol_class>"
           maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" 
          keystoreFile="conf/.ssl/keystore.jks"        
           keystorePass="<encrypted_password>"/>

希望这可以帮助。



Answer 3:

面对同样的问题。 客户的需求“隐藏”的所有密码。

所以,最简单的方式来传递审核-从Tomcat的维基 。

转到页http://coderstoolbox.net/string/#!encoding=xml&action=encode&charset=none和编码传递到XML视图。

因此- <Connector>元素看起来像:

<Connector
  port="8443"
  protocol="HTTP/1.1"
  SSLEnabled="true"
  enableLookups="false"
  disableUploadTimeout="true"
  scheme="https"
  secure="true"
  clientAuth="want"
  sslProtocol="TLS"
  keystoreFile="conf/.ssl/keystore.jks"
  keyAlias="tomcat"
  keystorePass="&#99;&#104;&#105;&#107;&#115;"
  truststoreFile="conf/.ssl/trustedstore.jks"
  truststorePass="&#99;&#104;&#105;&#107;&#115;"
/>


Answer 4:

我们也面临着类似的问题,但是我们创建了自己的加密和解密逻辑来解决这个。 下面是代码

/* 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);

    }

}

另一类

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;
    }

}

其生成的散列代码逻辑

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);
    }

}

这是我们扩展了类org.apache.coyote.http11.Http11Nio2Protocol这是目前在Tomcat的狼-8.0.29.jar其存在于Tomcat的8的lib文件夹所以在编译这些类Tomcat的狼-8.0。 29.jar应当存在。

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("");
        }
    }

}

这是用户在cmd进入密码应被散列

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;
    }
}

在这里,您将您的密码键。 你应该改变它。

public class PasswordKey {

    private static String ENCRYPTION_KEY = "myKeysecretkey";

    protected static String getEncryptionKey()
    {
        return ENCRYPTION_KEY;
    }

}

编译上述类来生成与在CMD下面命令的类文件。 请记住Tomcat的土狼,8.0.29.jar应该出现在所有的Java文件都存在同一个文件夹。

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

做一个罐子使用CMD命令生成的类文件

jar -cvf  PasswordEncryptor.jar  *.class

这将创建一个jar文件PasswordEncryptor.jar

粘贴Tomcat8的lib文件夹中生成的PasswordEncryptor.jar。 即Apache的Tomcat的8.5.9 \ lib中

现在去该位置和类型如下命令生成散列密码。

java -cp ".;PasswordEncryptor.jar" ClientForPasswordGeneration

现在去Apache的Tomcat的8.5.9 \ conf以编辑的server.xml

在证书的keystorpasss使用散列密码

<Connector port="9443" protocol="Http11Nio2Protocol" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
        keystoreFile="C:\Certificates\SSLCert.cert" keystorePass="nOS74yuWW4s18TsL2UJ51A=="/>

请注意该协议是自定义类的名称。

希望这会帮助你。

谢谢



Answer 5:

这里有一个方便的Perl的一个班轮到XML编码密码:

$ perl -pe 's/(.)/"&#".ord($1).";"/eg;' <<< 'secret'
# &#115;&#101;&#99;&#114;&#101;&#116;


文章来源: Encrypt tomcat keystore password