[JAVA] Elektronisches Zertifikat dies und das

Was du machen willst

Da dies die erste Implementierung der XML-Signatur ist, habe ich beschlossen, fortzufahren und verschiedene Notizen zu hinterlassen.

Operation

  1. Importieren Sie das Zertifikat im PKCS12-Format (.p12) in den Java-Keystore (cacert).
  2. Ändern Sie jeden von DB erhaltenen Parameter (falls erforderlich).
    cacert-Pfad, Keystore-Passwort, Alias, Verschlüsselungsalgorithmus, Digest-Algorithmus, Signaturalgorithmus usw. .. ..

Der obige Vorgang ist jedes Mal erforderlich, wenn das elektronische Zertifikat ersetzt wird.

Wonach schauen

Was ist ein elektronisches Zertifikat? ??

Was ist "Normalisierung" elektronischer Zertifikate? http://www.atmarkit.co.jp/fxml/tanpatsu/16xmlsecurity/xmlsecurity02.html

Informationen zum RSA-Schlüssel- und Zertifikatdateiformat https://qiita.com/kunichiko/items/12cbccaadcbf41c72735

Extrahieren Sie den privaten Schlüssel, das Zertifikat und die Zwischenzertifizierungsstelle aus der PKCS # 12-Datei https://qiita.com/cs_sonar/items/f2753ffdebb1c67d5302

So erstellen Sie ein selbstsigniertes Zertifikat https://qiita.com/akito1986/items/8eb41f5a43bb9421ae79

Wie signiere ich XML in Java? ??

XML-Signatur mit der XML-Signatur-API von Java http://qiita.com/KevinFQ/items/4e2484a659b618530e72

Keytool-Befehlsliste http://itref.fc2web.com/java/keytool.html

[Java] Zertifikate zum Schlüsselspeicher in Java hinzufügen / daraus löschen https://blogs.yahoo.co.jp/dk521123/37097725.html

Verschiedene Notizen

Konvertieren Sie vom Serverzertifikat pem in crt

$ openssl x509 -outform der in server-crt.pem -out server-crt.crt

Konvertieren Sie vom Serverzertifikat pem nach p12

$ openssl pkcs12 -export -out server-crt.p12 -in server-crt.pem -inkey server-privatekey.pem -passin pass:root -passout pass:root

Serverzertifikat p12 ⇒ In CRT konvertieren

$ openssl pkcs12 -in server-crt.p12 -clcerts -nokeys -out server-crt.crt

Serverzertifikat p12 ⇒ In cer konvertieren

$ openssl pkcs12 -in server-crt.p12 -des -out server-crt.cer

Keytool (Schlüssel- und Zertifikatverwaltungstool)

Installieren Sie das Keytool

https://jp.globalsign.com/support/faq/331.html

Erstellen Sie eine Keystore-Datei

Befehlsreferenz: https://docs.oracle.com/javase/jp/6/technotes/tools/windows/keytool.html

Es scheint, dass Java nicht automatisch aktualisiert werden kann, wenn sich die Cacerts ändern. Backup erforderlich. http://d.hatena.ne.jp/uunfo/20110813/1313242092

keytool -genkeypair -keysize 2048 -keyalg RSA -sigalg SHA256withRSA -alias testcrt -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -storepass changeit

** Hinzugefügt am 16.10.2017 ** Erstellen Sie überall eine Keystore-Datei (Wenn der allgemeine Name test1 lautet, lautet die Organisationseinheit test2, die Organisation test3 und der zweistellige Ländercode JP.)

$ keytool -genkey -dname "cn=test1, ou=test2, o=test3, c=JP" -Keystore (Keystore-Dateiname).keystore) -Alias (Name, der das Zertifikat / den Schlüssel im KeyStore identifiziert)-Tastatur (Zertifikat / Schlüsselkennwort * 6 Zeichen oder mehr)-Storepass (Key Store Passwort)-keyalg RSA -keysize 2048 -validity 10000

Referenz (pro Schlüsselpaargenerierung) https://docs.oracle.com/javase/jp/8/docs/technotes/tools/unix/keytool.html

Fügen Sie dem Keystore ein Serverzertifikat hinzu

Ich dachte, es wäre eine gute Idee, das Zertifikat als externe Ressource offen zu lassen, und überlegte daher, das Zertifikat in den Schlüsselspeicher zu importieren.

Importieren Sie die Cer-Datei in den Keystore

Wenn ich versuche, eine CRT-Datei mit dem folgenden Befehl zu importieren, wird die Fehlermeldung "Keytool-Fehler: java.lang.Exception: Eingabe ist kein X.509-Zertifikat" angezeigt. Import mit cer.

$ keytool -import -alias testkey -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -file server-crt.cer

Importieren Sie die p12-Datei in den Keystore http://blogger.fastriver.net/2014/10/keytool.html

Wenn Sie keinen Alias (Unterscheidungsnamen) angeben, wird dieser standardmäßig mit dem Namen "1" importiert. Wenn Sie einen Alias hinzufügen möchten, fügen Sie eine Option wie "-srcalias 1 -destalias (beliebiger Aliasname)" hinzu.

$ keytool -importkeystore -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -srckeystore server-crt.p12 -srcstoretype PKCS12 -srcalias 1 -destalias testcrt -srcstorepass root -deststorepass changeit

Überprüfen Sie das importierte Zertifikat

$ keytool -list -v -alias testcrt -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -keypass root -storepass changeit

Löschen Sie das importierte Zertifikat aus dem Keystore

$ keytool -delete -alias testcrt -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -keypass root -storepass changeit

Ändern Sie den Aliasnamen (beim Wechsel von 11111111 zu 22222222).

$ keytool -changealias -srcalias 11111111 -destalias 22222222 -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -keypass root -storepass changeit

Verlängern Sie das Ablaufdatum des Zertifikats (bei Einstellung nach 2000 Tagen)

$ keytool -selfcert -alias testcrt -validity 2000 -keystore "C:\Program Files\Java\jreX.X.X_XXX\lib\security\cacerts" -keypass root -storepass changeit

Java-Code abgeschlossen

createSignedXml.java


    public String createSignedXml(String fileName)
            throws Exception {

        //Dokumentinstanz erstellen
        DocumentBuilder documentBuilder = null;
        documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

        Document document = documentBuilder.newDocument();

        //DOM-Generierung eines XML-Dokuments (weggelassen)

        //Erstellung der XML-Signatur
        //p12 Dateipfad
        File certDir = "XXXXXX";
        //Liste der Zertifikatdateien unter dem Zertifikatverzeichnis (vorausgesetzt, es ist nur eine Datei vorhanden)
        File[] certP12List = certDir.listFiles((FileFilter) new SuffixFileFilter(".p12"));
        //Zertifikatdatei
        File certP12File = null;
        //Rufen Sie den Pfad der Keystore-Datei ab
        String keyStoreFilePath = "/usr/java/jdkX.X.X_XXX/jre/lib/security/testkeystore";
        //Keystore-Datei abrufen
        File keyStoreFile = new File(keyStoreFilePath);
        //Keystore-Passwort
        String keyStorePass = "root";
        //Zertifikat Passwort
        String certificatePass = "changeit";

        //Fehler, wenn mehrere p12-Dateien abgelegt werden
        if (certP12List.length == 1) {
            certP12File = certP12List[0];
        } else {
            throw new IOException();
        }

        try {
            //Holen Sie sich den Keystore
            KeyStore keyStore = getKeyStore(keyStoreFile, keyStorePass);

            //Distinguished Name: Beziehen Sie ein Zertifikat, das XXX entspricht, aus dem Schlüsselspeicher
            X509Certificate x509cert = getCertificate(keyStore, XXX);

            //Flag für die Beurteilung des Imports von Zertifikaten
            boolean importFlg = false;

            //Überprüfen Sie das Ablaufdatum
            // 0:Das importierte Zertifikat liegt innerhalb des Ablaufdatums, 1:Das importierte Zertifikat ist abgelaufen,
            // 2:Externes Ressourcenzertifikat ist abgelaufen, 3:Beide sind abgelaufen, 4:Importfehler
            int checkResult = 0;

            if (x509cert != null) {
                //Ablaufprüfung von Zertifikaten in externen Ressourcen und importierten Zertifikaten
                checkResult = checkCertificateExpired(x509cert, XXX, keyStoreFile, certP12File, keyStorePass, certificatePass);

                //Das importierte Zertifikat ist abgelaufen
                if (checkResult == 1) {
                    //Distinguished Name: XXX Zertifikat löschen
                    deleteProcessExec(XXX, keyStoreFile, certificatePass, keyStorePass);

                    importFlg = true;
                }
            } else {
                importFlg = true;
            }

            //Wenn das in den Schlüsselspeicher importierte Zertifikat abgelaufen ist
            //Neues Zertifikat erneut importieren
            if (importFlg) {
                //Führen Sie den Zertifikatimport durch
                importProcessExec(keyStoreFile, XXX, certP12File, certificatePass, keyStorePass);

                //Besorgen Sie sich den Keystore erneut
                keyStore = getKeyStore(keyStoreFile, keyStorePass);

                //Distinguished Name: Beziehen Sie ein Zertifikat, das XXX entspricht, erneut aus dem Keystore
                x509cert = getCertificate(keyStore, XXX);

                //Ablaufdatum prüfen
                checkResult = checkCertificateExpired(x509cert, keyStoreFile, certP12File, keyStorePass, certificatePass);
            }

            //Sowohl das in der externen Ressource platzierte Zertifikat als auch das importierte Zertifikat sind abgelaufen
            //Fehler beim Importieren eines externen Ressourcenzertifikats
            if (checkResult >= 3) {
                //Distinguished Name: XXX Zertifikat löschen
                deleteProcessExec(XXX, keyStoreFile, certificatePass, keyStorePass);

                throw new CertificateException();
            }

            //Holen Sie sich den privaten Schlüssel
            RSAPrivateKey privateKey = (RSAPrivateKey) keyStore.getKey(XXX, certificatePassArray);

            //Signierkontext erstellen
            DOMSignContext dsc = new DOMSignContext(privateKey, document.getDocumentElement());

            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

            //Referenzelement erstellen
            Reference ref = fac.newReference
                    ("#XXXXXX", fac.newDigestMethod(DigestMethod.SHA256, null),
                            Collections.singletonList
                                    (fac.newTransform(Transform.ENVELOPED,
                                            (TransformParameterSpec) null)), null, null);

            //Signaturinformationen erstellen
            SignedInfo si = fac.newSignedInfo
                    (fac.newCanonicalizationMethod
                            (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                                    (C14NMethodParameterSpec) null),
                            fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null),
                            Collections.singletonList(ref));

            KeyInfoFactory kif = fac.getKeyInfoFactory();
            X509Data x509Data = kif.newX509Data(Collections.singletonList(x509cert));
            KeyInfo ki = kif.newKeyInfo(Collections.singletonList(x509Data));

            //Zeichen.
            XMLSignature signature = fac.newXMLSignature(si, ki);
            signature.sign(dsc);

        } catch (XMLSignatureException e) {
            throw new XMLSignatureException("Fehler beim Generieren oder Validieren der XML-Signatur", e);
        } catch (MarshalException e) {
            throw new MarshalException(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new InvalidAlgorithmParameterException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new NoSuchAlgorithmException(e);
        } catch (KeyStoreException e) {
            throw new KeyStoreException(e);
        } catch (CertificateException e) {
            throw new CertificateException(e);
        } catch (UnrecoverableKeyException e) {
            throw new UnrecoverableKeyException();
        }

        return this.write(document);
    }

    /**
     *Holen Sie sich den Keystore
     *
     * @param keyStoreFile Keystore-Datei
     * @param keyStorePass Keystore-Passwort
     * @Rückgabe des Keystore-Objekts keyStore
     */
    private KeyStore getKeyStore(File keyStoreFile, String keyStorePass) {
        KeyStore keyStore = null;

        try (FileInputStream keyStoreStream = new FileInputStream(keyStoreFile)) {
            //Keystore-Typ:JKS(Nehmen Sie für PKCS12 das Argument"PKCS12"Reparieren)
            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(keyStoreStream, keyStorePass.toCharArray());
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            //TODO automatisch generierter Fangblock
            e.printStackTrace();
        }

        return keyStore;
    }

    /**
     *Holen Sie sich ein Zertifikat, das Ihrem definierten Namen entspricht, aus dem Keystore
     *
     * @param keyStore Keystore-Objekt
     * @param alias Distinguished name
     * @Zertifikat zurückgeben Zertifikatobjekt
     */
    private X509Certificate getCertificate(KeyStore keyStore, String alias){
        X509Certificate certificate = null;
        try {
            certificate = (X509Certificate) keyStore.getCertificate(alias);
        } catch (KeyStoreException e) {
            //TODO automatisch generierter Fangblock
            e.printStackTrace();
        }
        return certificate;
    }

    /**
     *Ablaufprüfung des Zertifikats
     *
     * @param x509cert X509-Zertifikatobjekt
     * @param keyStoreFile Keystore-Datei
     * @param certFile Zertifikatdatei
     * @param keyStorePass Keystore-Passwort
     * @param certificatePass Zertifikat Passwort
     * @param srcAlias Temporärer definierter Name unmittelbar nach dem Import
     * @return 0:Das importierte Zertifikat liegt innerhalb des Ablaufdatums, 1:Das importierte Zertifikat ist abgelaufen,
     * 2:Externes Ressourcenzertifikat ist abgelaufen, 3:Beide sind abgelaufen, 4:Fehler beim Importieren eines externen Ressourcenzertifikats
     */
    private int checkCertificateExpired(X509Certificate x509cert,
            File keyStoreFile, File certFile, String keyStorePass, String certificatePass,
            String srcAlias) {
        //Verarbeitungsergebnis
        int result = 0;
        //Ablaufflag des importierten Zertifikats
        // true:Abgelaufen, false:Innerhalb des Ablaufdatums
        boolean importExpiredFlg = false;
        //Ablaufflag für Zertifikate, die auf externen Ressourcen platziert sind
        boolean extExpiredFlg = false;
        //Ruft das Ablaufdatum des in den Keystore importierten Zertifikats ab
        Date importExpiredDate = x509cert.getNotAfter();
        //Aktuelles Datum und Uhrzeit
        Date now = new Date();

        /**************************Ablaufprüfung des importierten Zertifikats START**************************/

        //Stellen Sie fest, ob das importierte Zertifikat abgelaufen ist
        if (now.compareTo(importExpiredDate) > 0) {
            //Wenn es abgelaufen ist
            importExpiredFlg = true;
            result = 1;
        } else {
            //Da es innerhalb des Ablaufdatums liegt, sind keine weiteren Überprüfungen erforderlich
            return 0;
        }
        /***************************Ablaufprüfung des importierten Zertifikats END***************************/

        /***********************Ablaufprüfung für Zertifikate auf externen Ressourcen START**********************/

        try {
            //Temporärer Distinguished Name
            String destAlias = System.currentTimeMillis();

            //Importbefehl ausführen
            importProcessExec(keyStoreFile, destAlias, certFile, certificatePass, keyStorePass);

            //Holen Sie sich den Keystore
            KeyStore tmpKeyStore = getKeyStore(keyStoreFile, keyStorePass);
            //Distinguished Name: Holen Sie sich ein Zertifikat, das mit destAlias übereinstimmt, aus dem Keystore
            X509Certificate tmpCert = getCertificate(tmpKeyStore, destAlias);

            //Rufen Sie das Ablaufdatum des importierten Zertifikats ab
            Date extExpiredDate = null;
            if (tmpCert != null) {
                extExpiredDate = tmpCert.getNotAfter();
            } else {
                //Importfehler
                return 4;
            }

            //Vergleichen Sie die aktuelle Uhrzeit mit dem Ablaufdatum des Zertifikats der externen Ressource
            if (now.compareTo(extExpiredDate) > 0) {
                //Wenn es abgelaufen ist
                extExpiredFlg = true;
                result = 2;
            }

            //Befehl ausführen, um vorübergehend importiertes Zertifikat zu löschen
            deleteProcessExec(destAlias, keyStoreFile, certificatePass, keyStorePass);

        } catch(InterruptedException e) {
            //TODO automatisch generierter Fangblock
            e.printStackTrace();
        }
        /**********************Ablaufprüfung ENDE für Zertifikate, die auf externen Ressourcen abgelegt sind*********************/


        //Importierte Zertifikate und Zertifikate für externe Ressourcen
        //Wenn beide abgelaufen sind, Ergebnis:3
        if (importExpiredFlg && extExpiredFlg) {
            result = 3;
        }

        return result;

    }

    /**
     *Führen Sie den Befehl zum Löschen des Zertifikats aus.
     *
     * @param alias Distinguished name
     * @param keyStoreFile Keystore-Datei
     * @param certificatePass Zertifikat Passwort
     * @param keyStorePass Keystore-Passwort
     * @return true:Erfolgreiche Fertigstellung, false:Abnormale Beendigung
     * @throws InterruptedException
     */
    private boolean deleteProcessExec(String alias, File keyStoreFile, String certificatePass,
            String keyStorePass)
            throws InterruptedException {
        //Rufen Sie den Befehl ab, um das in den Keystore importierte Zertifikat zu löschen
        List<String> command = getDeleteCommand(alias, keyStoreFile, certificatePass, keyStorePass);
        //Befehlsausführung löschen
        return processExec(command);
    }

    /**
     *Rufen Sie den Befehl zum Löschen des Zertifikats ab.
     *
     * @param alias Distinguished name
     * @param keyStoreFile Keystore-Datei
     * @param certificatePass Zertifikat Passwort
     * @param keyStorePass Keystore-Passwort
     * @Befehl resultList delete zurückgeben
     */
    private List<String> getDeleteCommand(String alias, File keyStoreFile, String certificatePass,
            String keyStorePass) {
        //Befehl zum Löschen des in den Schlüsselspeicher importierten Zertifikats
        String command = "keytool -delete -alias %alias% -keystore %keyStoreFilePath% -keypass %certificatePass% -storepass %keyStorePass%";

        //Befehl in String-Array aufteilen
        String[] commandList = command.split(" ");

        List<String> resultList = new ArrayList<String>();
        for (String cmd : commandList) {
            switch (cmd) {
            case "%alias%":
                cmd = cmd.replace("%alias%", alias);
                break;
            case "%keyStoreFilePath%":
                cmd = cmd.replace("%keyStoreFilePath%", keyStoreFile.getPath());
                break;
            case "%certificatePass%":
                cmd = cmd.replace("%certificatePass%", certificatePass);
                break;
            case "%keyStorePass%":
                cmd = cmd.replace("%keyStorePass%", keyStorePass);
                break;
            }
            resultList.add(cmd);
        }

        return resultList;
    }

    /**
     *Führen Sie den Zertifikatimportbefehl aus.
     *
     * @param certFilePath Zertifikatdatei
     * @param destAlias Distinguished name
     * @param keyStoreFilePath Keystore-Datei
     * @param certificatePass Zertifikat Passwort
     * @param keyStorePass Keystore-Passwort
     * @return true:Erfolgreiche Fertigstellung, false:Abnormale Beendigung
     * @throws InterruptedException
     */
    private boolean importProcessExec(File keyStoreFile, String destAlias, File certFile,
            String certificatePass,
            String keyStorePass) throws InterruptedException {
        //Befehl zum Importieren des Zertifikats
        List<String> command = getImportCommand(keyStoreFile, destAlias, certFile, certificatePass,
                keyStorePass);
        //Importbefehl ausführen
        return processExec(command);
    }

    /**
     *Befehl zum Importieren von Zertifikaten abrufen.
     *
     * @param certFilePath Zertifikatdatei
     * @param destAlias Distinguished name
     * @param keyStoreFilePath Keystore-Datei
     * @param certificatePass Zertifikat Passwort
     * @param keyStorePass Keystore-Passwort
     * @Befehl resultList import zurückgeben
     */
    private List<String> getImportCommand(File keyStoreFile, String destAlias, File certFile,
            String certificatePass, String keyStorePass) {
        //Befehl zum Importieren des Zertifikats
        String command = "keytool -importkeystore -keystore %keyStoreFilePath% -srckeystore %certFilePath% -srcstoretype PKCS12 -srcalias 1 -destalias %destalias% -srcstorepass %certificatePass% -deststorepass %keyStorePass%";

        //Befehl in String-Array aufteilen
        String[] commandList = command.split(" ");

        List<String> resultList = new ArrayList<String>();

        for (String cmd : commandList) {
            switch (cmd) {
            case "%keyStoreFilePath%":
                cmd = cmd.replace("%keyStoreFilePath%", keyStoreFile.getPath());
                break;
            case "%certFilePath%":
                cmd = cmd.replace("%certFilePath%", certFile.getPath());
                break;
            case "%destalias%":
                cmd = cmd.replace("%destalias%", destAlias);
                break;
            case "%certificatePass%":
                cmd = cmd.replace("%certificatePass%", certificatePass);
                break;
            case "%keyStorePass%":
                cmd = cmd.replace("%keyStorePass%", keyStorePass);
                break;
            }
            resultList.add(cmd);
        }

        return resultList;
    }

    /**
     *Führen Sie einen externen Prozess aus.
     *
     * @Befehl param Befehlsinhalt
     * @return true:Erfolgreiche Fertigstellung, false:Abnormale Beendigung
     */
    private boolean processExec(List<String> command) {
        //Verarbeitungsergebnis
        boolean result = false;

        try {
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            Process Process = processBuilder.start();

            //Warten Sie, bis der Vorgang normal endet
            if (Process.waitFor() == 0) {
                result = true;
                log.info("Process Success: " + command.toString());
            } else {
                log.warn("Process Failed: " + command.toString());
            }

            //Standardausgabe
            String strInput;
            BufferedReader ipbr = new BufferedReader(new InputStreamReader(Process.getInputStream()));
            while((strInput = ipbr.readLine()) != null) {
                log.info(strInput);
            }
            ipbr.close();

            //Fehlerausgabe
            String strErr;
            BufferedReader erbr = new BufferedReader(new InputStreamReader(Process.getErrorStream()));
            while((strErr = erbr.readLine()) != null) {
                log.info(strErr);
            }
            erbr.close();

            //InputStream im Hintergrund nach Verwendung von ProcessBuilder, OutputStream,ErrorStream wird geöffnet.
            //Schließen Sie alle Streams, um zu vermeiden, dass Ihnen die Ressourcen ausgehen.
            Process.getInputStream().close();
            Process.getOutputStream().close();
            Process.getErrorStream().close();
        } catch (InterruptedException | IOException e) {
            //TODO automatisch generierter Fangblock
            e.printStackTrace();
        }

        return result;
    }

Recommended Posts

Elektronisches Zertifikat dies und das
[Rails] strftime dies und das
Base64 Encoder dies und das
Dies und das von JDK
Dies und das über Base64 (Java)
Dies und das der ausschließlichen Kontrolle
Dies und das von Swift Corner Radius
Dies und das der bedingten Verzweigung der Schienenentwicklung
Dies und das zum Bearbeiten von ini in Java. : inieditor-java
Ich habe versucht, dies und das von Spring @ Transactional zu überprüfen
Zeichenkettenoperation dies und das-Java-Version-
Dies und das der Implementierung der zeitlichen Beurteilung von Daten in Java