Back to The tech awesomeness
Table of contents
Java chapters

The article for today.

I have found that code and then have added the corresponding changer.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * This class explains how to change default java trust store(cacerts file)
 * password using Java API (C:\Program Files\Java\jdk\jre\lib\security\cacerts) 
 * and (/Library/Java/JavaVirtualMachines/jdk/Contents/Home/lib/security)
 * and to list out certificates from trust store
 */
public class TrustStorePasswordChanger {

    private static final String CACERTIFICATES_PATH = "/lib/security/cacerts";

    private static final String DEFAULT_CACERTIFICATES_PASSWORD = "changeit";
    private static final String NEW_CACERTIFICATES_PASSWORD = "****************";
    private static final String TRUST_STORE_FILE_PATH =
            System.getProperty("java.home")
            + CACERTIFICATES_PATH.replace('/', File.separatorChar);
    private static final String OUTPUT_FILE_PATH = TRUST_STORE_FILE_PATH;
    
    /**
     * Main method for entry point.
     * @param args 
     */
    public static void main(String[] args) {
        InputStream fileInputStream =
                getInputStreamFromFilePath(TRUST_STORE_FILE_PATH);
        byte[] keyBytes;

        try {
            keyBytes = updateTrustStorePass(fileInputStream,
                    DEFAULT_CACERTIFICATES_PASSWORD,
                    NEW_CACERTIFICATES_PASSWORD);
            // to read and display certificates from trust store
            displayCertificatesFromTrustStore(keyBytes,
                    DEFAULT_CACERTIFICATES_PASSWORD);
            
            // to read and display certificates from trust store again
            displayCertificatesFromTrustStore(keyBytes,
                    NEW_CACERTIFICATES_PASSWORD);
        
            ByteArrayInputStream byteArrayInputStream =
                    new ByteArrayInputStream(keyBytes);
            Files.copy(byteArrayInputStream, Paths.get(OUTPUT_FILE_PATH));
        } catch (FileNotFoundException e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        } catch (IOException e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
            System.out.println(
                    "Expected java.security.UnrecoverableKeyException:"
                    + " Password verification failed.");
        }
    }
    
    /**
     * This method takes cacerts input and updates trustore password
     * 
     * @param certStream
     * @param oldPassword
     * @param newPassword
     * @return
     * trust store object in bytes * @throws Exception
     */
    private static byte[] updateTrustStorePass(
            InputStream certificateInputStream,
            String oldPassword,
            String newPassword) throws FileNotFoundException {
        byte[] trustStore = new byte[1024];
        KeyStore inboundCertificate;
        try {
            inboundCertificate = KeyStore.getInstance(KeyStore.getDefaultType());
            char[] oldPasswordPhrase = oldPassword.toCharArray();
            char[] newPasswordhrase = newPassword.toCharArray();
            inboundCertificate.load(certificateInputStream, oldPasswordPhrase);
            try (ByteArrayOutputStream byteArrayOutputStream =
                    new ByteArrayOutputStream(inboundCertificate.size())) {
                inboundCertificate.store(
                        byteArrayOutputStream, newPasswordhrase);
                trustStore = byteArrayOutputStream.toByteArray();
            }
        } catch (KeyStoreException | NoSuchAlgorithmException
                | CertificateException | IOException e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        }
        
        return trustStore;
    } 
    
    /** 
     * This method is used to iterate trust store and display certificates
     * http://thetechawesomeness.ideasmatter.info/summation.html;2022-05-11
     * 
     * @param keyBytes
     * @param password
     */
    private static void displayCertificatesFromTrustStore(
            byte[] keyBytes, String password) {
        try {
            InputStream inputStream = convertByteIntoInputStream(keyBytes);
            KeyStore keyStore = KeyStore.getInstance("jks");
            keyStore.load(inputStream, password.toCharArray());
            PKIXParameters params = new PKIXParameters(keyStore);
            for (TrustAnchor trustAnchor : params.getTrustAnchors()) {
                // to get certificate
                X509Certificate c = trustAnchor.getTrustedCert();
                Principal subject = c.getSubjectDN();
                System.out.println("\n\n\n\n");
                System.out.println("Subject: " + subject);
                System.out.println("===============================" +
                        keyStore.getCertificateAlias(c) +
                        "==============================");
                System.out.println("Version :" + c.getVersion());
                System.out.println("Serial Number :" + c.getSerialNumber());
                System.out.println("Signature Algorithm : " + c.getSigAlgName());
                System.out.println("Valid From : " + c.getNotBefore());
                System.out.println("Valid To : " + c.getNotAfter());
                Collection < List < ? > > issuer = c.getIssuerAlternativeNames();
                if (issuer != null) {
                    issuer.forEach((issuerEntry) -> {
                        issuerEntry.forEach((issuerString) -> {
                            System.out.println("Alternative issuer name: "
                                    + issuerString);
                        });
                    });
                } else {
                    System.out.println("No alternative issuer names. ");
                }
                System.out.println(c.getIssuerDN().getName()); 
            }
        } catch (CertificateException | KeyStoreException
                | NoSuchAlgorithmException | InvalidAlgorithmParameterException
                | IOException e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        }
    }

    /** 
     * This method explains how to convert byte into input stream 
     * 
     * @param bytes
     * @return
     */
    private static InputStream convertByteIntoInputStream(byte[] bytes) {
        InputStream inputStream = null;
        try {
            inputStream = new ByteArrayInputStream(bytes);
        } catch (Exception e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        } finally {
            try { 
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
            }
        }
        return inputStream;
    }

    /**
     * The following method returns inputStream for given file path 
     * 
     * @param filePath * @return 
     */
    private static InputStream getInputStreamFromFilePath(String filePath) {
        InputStream trustStoreInputStream = null;
        try {
            trustStoreInputStream = new FileInputStream(new File(filePath));
        } catch (FileNotFoundException e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        } return trustStoreInputStream;
    }

    /**
     * Addition of a certificate to the cacerts trust store
     * if it's not already included
     * 
     * @param alias The alias for the certificate, if added
     * @param certInputStream The certificate input stream
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    private static void addCertificateToTrustStore(
            String alias, InputStream certificateInputStream)
            throws KeyStoreException, NoSuchAlgorithmException,
            CertificateException, IOException {
        //to get default cacerts file
        final File caCertificatesFile = new File(System.getProperty("java.home")
                + CACERTIFICATES_PATH);
        if (!caCertificatesFile.exists()) {
            throw new FileNotFoundException(
                    caCertificatesFile.getAbsolutePath());
        }

        final KeyStore caCertificatesInputStream;
        try ( //to load cacerts keystore
                FileInputStream cacertificatesInputStream =
                        new FileInputStream(caCertificatesFile);
                certificateInputStream) {
            caCertificatesInputStream =
                    KeyStore.getInstance(KeyStore.getDefaultType());
            caCertificatesInputStream.load(cacertificatesInputStream,
                    DEFAULT_CACERTIFICATES_PASSWORD.toCharArray());

            //to load certificate from input stream
            final CertificateFactory certificateFactory =
                    CertificateFactory.getInstance("X.509");
            final Certificate certificate =
                    certificateFactory.generateCertificate(
                            certificateInputStream);
            certificateInputStream.close();

            //to check if cacerts contains the certificate
            if (caCertificatesInputStream.getCertificateAlias(certificate)
                    == null) {
                //cacerts doesn't contain the certificate, add it
                caCertificatesInputStream.setCertificateEntry(
                        alias, certificate);
                try ( //to write the updated cacerts keystore
                        FileOutputStream caCertificateFileOutputStream =
                                new FileOutputStream(caCertificatesFile)) {
                    caCertificatesInputStream.store(
                            caCertificateFileOutputStream,
                            DEFAULT_CACERTIFICATES_PASSWORD.toCharArray());
                } catch (FileNotFoundException e) {
                    Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
                }
            }
        } catch (Exception e) {
            Logger.getLogger(TrustStorePasswordChanger.class.getName())
                    .log(Level.WARNING, null, e);
        }
    }
}

Змінюючи пароль довіренного сховища.

Оновлення від 2021-11-11.

The update as of 2021-11-11.

Щоби такі зміни автоматизувати поки немає автоматичної особливості для цього кода можливо використати crontab чи @Scheduled якщо доступні.

З за цього якщо так то знову там може бути багато мінорно подібних автоматизацій.

Але це лише також може показати ділення систем на ті що мають довіренне сховище і такі що не мають його.

Наприклад до появи подібного сховища в деяких ППіНТВСуІ, я не зберігав веб місця і веб сайти а саме УРР щодо для логінів, тож мені просто не відомо які і де є для логінів.

Більше того може здатися що я маю зберігати їх відтепер. Але воно ймовірно пропонує прочитати про це десь. Нібито це достатньо унікальна особливість без скарг роками щоби додатково і читати про неї.

Але воно також лише може показати відсутність визначаючих поміток для подібної не унікальної особливості котра нарешті з'явилась у деяких програмах після стількох багатьох скарг. Наприклад про те хто може бачити ті цінні дані. Також про її відкрито кодовість, закрито кодовість і тому подібне.

To automate such changing till there is no atomatic feature for this code it is possible to use crontab if available or @Scheduled if available.

Because of that, if so, there it can be many different minorly unique ones of those again.

But it still also can show the division of systems in those ones which have a trust store and those ones which do not have such ones.

For example till the appearance of similar storage in some browsers for web sites, I did not track web sites for logins, so it is unknown for me which and where they are for logins.

Moreover it seems that I should keep track of those ones now. But it probably proposes to read about it somewhere. As if it is unique complaintly absent enough during many years to read about it additionally.

But it still also can show the absence of the identifiable marks for such non unique complaintly absent enough feature and alike which finally appeared in some ones after so many complaints. For example who can see that precious data. Also about open source, closed source and so on.

Оновлення від 2021-11-13.

The update as of 2021-11-13.

У деяких перемикачевих системах система керування для особливості були додані а потім оголошені застарілими і видалені або розширені більше ніж однією.

In some triggeral systems the management system per feature was added and then deprecated and removed or extended by more than one.