Montag, Januar 20, 2020

Verschlüsseln tomcat-keystore-Kennwort

Gibt es eine option zum verschlüsseln keystorePass Wert in tomcat server.xml?
Ich will nicht, dass es eine nur-text –

    <Connector port="8403" //...
        keystorePass="myPassword" /> 
  • Wo dachten Sie speichern die Schlüssel zum entsperren das Kennwort zum entsperren des keystorePass? Nur aus Interesse.
  • Ich bin mir bewusst, dass dies nicht eine einfache Frage. Ich verlange zu wissen, ob es eine standard-Lösung.
  • Nein, es gibt auf standard-Lösung außer vielleicht das überschreiben des Connector als ich unten erwähnt, aber das ist in keiner Weise ein standard-Lösung und mehr ein rechter hacken.
InformationsquelleAutor Adi Baron | 2013-04-24

5 Kommentare

  1. 12

    Wenn jemand hat Zugang zu Ihren server.xml die nur-text-Wert Ihrer keystorePass erscheinen, sind nur eine Ihrer sorgen.

    Wenn jemand Zugriff hat, von dort, Sie tun könnte viel mehr Schaden. Verschlüsseln Sie das Kennwort hier ist wirklich nur das verschieben das problem an anderer Stelle als Sie dann jemanden finden konnte, der Verschlüsselungs-Schlüssel für diesen Verschlüsselungsschlüssel (ein bisschen wie eine russische Puppe).

    Wenn Sie möchten, um das Kennwort zu verschlüsseln, müssen Sie das überschreiben der Stecker
    Umsetzung zum entschlüsseln der verschlüsselten Kennwort, so dass der eigentliche pwd ist
    zugänglich oder verfügbar zu tomcat.

    • Eine kleine Korrektur – Anschlüsse sind endgültig (zumindest bei tomcat 7) es ist das Protokoll, muss man überschreiben
    • Könnte ich bitte Fragen Sie Sie bitte, welches Protokoll braucht man überschreiben? und wie?
    • Ich bin nicht einverstanden mit dem oben. Der springende Punkt bei der Sicherheit ist eine mehrschichtige Verteidigung. In der cloud zum Beispiel ist es möglich, um Daten zu verschlüsseln, und aktivieren Sie dann den Zugriff auf die Verschlüsselungsschlüssel über IAM (aws). Halten Sie Passwörter auf der Festplatte im nur-text ist einfach nur schlecht Sicherheit. Solche Geheimnisse sollten immer nur sein in der Prozess-Speicher in Ihren Entschlüsselter form.
  2. 11

    Gibt es einen besseren Weg, als einfach mit der XML-Codierung.

    Erstellen eines Verschlüsselungs-Klasse zum verschlüsseln und entschlüsseln Ihr Passwort.

    Und überschreiben Http11Nio2Protocol Klasse, etwas ähnliches wie den folgenden code.

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

    }

    Hinweis: EncryptService ist unsere eigene Verschlüsselung-Klasse.

    Und konfigurieren Sie die überschriebene Klasse in das Protokoll-Attribut in server.xml wie unten.

    <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>"/>
    

    Hoffe, das hilft.

    • Ja, das ist genau das, was wir Taten. Siehe mein Kommentar auf die Antwort akzeptiert.
    • Ich habe versucht, diese Lösung, aber ich bekomme die Fehlermeldung: java.lang.ClassNotFoundException: listener.Http11Nio2Protocol.
    • Ich habe implementiert, die Es Lesen nicht die Methode setKeystorePass!!
  3. 6

    Konfrontiert mit dem gleichen problem. Die Anforderungen der Kunden zu „verstecken“ alle Kennwörter.

    So, einfachste Weg, um pass-audit – von Tomcat Wiki.

    Gehe zu Seite http://coderstoolbox.net/string/#!encoding=xml&Aktion=encode&charset=none und Kodieren Sie übergeben, um der XML-Ansicht.

    Somit <Connector> – element sieht wie folgt aus:

    <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;"
    />
    
  4. 1

    Waren wir auch vor ähnlichen problem, aber wir haben unsere eigene Verschlüsselung und Entschlüsselung der Logik in Angriff zu nehmen. Hier ist der 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);
    
        }
    
    }
    

    Anderen Klasse

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

    Logik, die generierten Hash-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);
        }
    
    }
    

    Dies ist, wo wir erweitert die Klasse org.apache.coyote.http11.Http11Nio2Protocol die in tomcat-coyote-8.0.29.jar die in den lib-Ordner von tomcat 8. So, während diese Klassen zu kompilieren tomcat-coyote-8.0.29.jar vorhanden sein sollten.

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

    Dies ist, wo Benutzer muss Passwort eingeben in cmd sollte zerlegt werden

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

    Dies ist, wo Sie halten Ihre Passwort-Schlüssel. Ändern Sie es.

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

    kompilieren oben genannten Klassen zu generieren, die class-Dateien mit den nachstehenden Befehl im cmd. Erinnern tomcat-coyote-8.0.29.jar vorhanden sein sollte in den gleichen Ordner, in dem alle java-Dateien vorhanden sind.

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

    Stellen Sie ein Glas mit der erzeugten class-Datei verwenden Sie diesen Befehl in cmd

    jar -cvf  PasswordEncryptor.jar  *.class
    

    Dadurch wird eine jar-Datei PasswordEncryptor.jar

    Fügen Sie den generierten PasswordEncryptor.jar in den lib-Ordner von Tomcat8. also apache-tomcat-8.5.9\lib

    Nun gehen Sie zu diesem Speicherort, und geben Sie unten den Befehl zum generieren des Hash-Passwort.

    java -cp ".;PasswordEncryptor.jar" ClientForPasswordGeneration
    

    Verschlüsseln tomcat-keystore-Kennwort

    Nun gehen Sie zur apache-tomcat-8.5.9\conf und Bearbeiten server.xml

    Verwenden Sie das gehashte Passwort in keystorpasss Zertifikat

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

    Mitteilung ist das Protokoll der benutzerdefinierten Klasse name.

    Hoffe, dies wird Ihnen helfen.

    Dank

  5. 0

    Hier ist eine praktische Perl-one-liner in XML Kodieren Passwort:

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

Kostenlose Online-Tests