Шифрование пароля хранилища ключей tomcat

есть ли возможность шифровать keystorePass значение в tomcat сервер.в XML? Я не хочу, чтобы это был простой текст

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

5 ответов


Если у кого-то есть доступ к вашему серверу.xml, простое текстовое значение вашего keystorePass появляются только одна из ваших забот.

Если у кого-то есть доступ оттуда, они могут причинить гораздо больше вреда. Шифрование пароля здесь действительно просто перемещает проблему в другое место, так как тогда кто-то может найти ключ шифрования для этого ключа шифрования (немного похоже на русскую куклу).

Если вы хотите зашифровать пароль, вы должны переопределить соединитель реализации расшифруйте зашифрованный пароль, чтобы реальный pwd доступно или доступно для tomcat.


есть лучший способ, чем просто использовать кодирование 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 - это наш собственный класс шифрования.

и настройте переопределенный класс в атрибуте протокола в сервер.в 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>"/>

надеюсь, что это помогает.


столкнулся с той же проблемой. Клиент требует "скрыть" все пароли.

Итак, самый простой способ пройти проверку - с Tomcat Wiki.

перейти на страницу 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;"
/>

мы также столкнулись с аналогичной проблемой, но мы создали нашу собственную логику шифрования и дешифрования для решения этой проблемы. Вот код

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

            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.апаш.койот.http11.Http11Nio2Protocol, который присутствует в tomcat-coyote-8.0.29.jar, который присутствует в папке lib tomcat 8. Поэтому при компиляции этих классов tomcat-coyote-8.0.29.сосуд должны присутствовать.

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

}

compile выше классов для создания файлов классов с командой ниже в cmd. Помните tomcat-coyote-8.0.29.jar должен присутствовать в той же папке, где присутствуют все файлы java.

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

сделайте банку с сгенерированным файлом класса, используя эта команда в cmd

jar -cvf  PasswordEncryptor.jar  *.class

это создаст файл Jar PasswordEncryptor.Джар

вставьте сгенерированный PasswordEncryptor.jar в папке lib Tomcat8. т. е. apache-tomcat-8.5.9\lib

Теперь перейдите в это место и введите ниже команду для создания хэшированного пароля.

java -cp ".;PasswordEncryptor.jar" ClientForPasswordGeneration

Enter The password and it will show hashed password

Теперь перейдите в apache-tomcat-8.5.9\conf и отредактируйте сервер.в 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=="/>

уведомления протокол пользовательское имя класса.

надеюсь, это поможет вам.

спасибо


вот удобный Perl One-liner для XML-кодирования пароля:

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