Hello,
Through several articles, I would like present the cryptographic mechanisms, types of keys, certificate, types of algorithms …etc:

 


KeyStore, JCEKS, SecretKey, PrivateKey, PublicKey, Certificate
 

  1. Presentation

    The Java™ Cryptography Architecture Standard Algorithm Name Documentation describes several KeyStore Types to used during the generation of a KeyStore’s instance (see https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html):

    • jceks = The proprietary keystore implementation provided by the SunJCE provider.
    • jks = The proprietary keystore implementation provided by the SUN provider.
    • pkcs12 = The transfer syntax for personal identity information as defined in PKCS #12.

     

    As described in the KeyStore JavaDoc https://docs.oracle.com/javase/7/docs/api/java/security/KeyStore.html KeyStore manages different types of entries. Each type of entry implements the KeyStore.Entry interface. Three basic KeyStore.Entry implementations are provided:

    • KeyStore.PrivateKeyEntry : This type of entry holds a cryptographic PrivateKey, which is optionally stored in a protected format to prevent unauthorized access. It is also accompanied by a certificate chain for the corresponding public key. Private keys and certificate chains are used by a given entity for self-authentication. Applications for this authentication include software distribution organizations which sign JAR files as part of releasing and/or licensing software.
    • KeyStore.SecretKeyEntry : This type of entry holds a cryptographic SecretKey, which is optionally stored in a protected format to prevent unauthorized access.
    • KeyStore.TrustedCertificateEntry : This type of entry contains a single public key Certificate belonging to another party. It is called a trusted certificate because the keystore owner trusts that the public key in the certificate indeed belongs to the identity identified by the subject (owner) of the certificate. This type of entry can be used to authenticate other parties.


     
     

  2. Tools: KeyStoreManagement Class
    In my previous posts, I exposed the use of PorteCle tool used in order to generate KeyStore/TrustStore, self-signed certificate,…etc:

    …. in this post, I would expose you my homemade utility class KeyStoreManagement composed of following methods in order to generate KeyStore/TrustStore, add/get/check secret key, private key, public key and certificate,…etc:

    • KeyStore createOrUseKeyStore(…) : creation or use of JCEKS Keystore managed by a password;
          private static KeyStore createOrUseKeyStore(String ksFileName, String ksPassword) throws Exception {
          	// KeyStore Types
              final KeyStore ks = KeyStore.getInstance("JCEKS"); // or KeyStore.getDefaultType()
      
              InputStream input = null;
              File f = new File(ksFileName);
              if (f.exists()) {
                  input = new FileInputStream(f);
                  // .keystore file already exists => load it
                  ks.load(input, ksPassword.toCharArray());
      
              } else {
                  // .keystore file not created yet => create it
                  ks.load(null, null);
                  ks.store(new FileOutputStream(ksFileName), ksPassword.toCharArray());
              }
      
              return ks;
          }
      
    • void addSecretKey(…) : method adding a password-protected secret key to the keystore. The SecretKeyEntry entry is password-protected.
          public void addSecretKey(String keyEntryName, String keyEntryPassword, SecretKey secretKey) throws Exception {
              KeyStore.SecretKeyEntry keyStoreEntry = new KeyStore.SecretKeyEntry(secretKey);
              KeyStore.PasswordProtection keyPassword = new KeyStore.PasswordProtection(keyEntryPassword.toCharArray());
              keyStore.setEntry(keyEntryName, keyStoreEntry, keyPassword);
              keyStore.store(new FileOutputStream(keyStoreFileName), keyStorePassword.toCharArray());
          }
      
    • void addCertificate(…) : method adding a NOT-protected certificate to the keystore. TheTrustedCertificateEntry is NOT protected. A Certificate contains the a public key.
          public void addCertificate(String keyEntryName, Certificate trustedCert) throws Exception {
              KeyStore.TrustedCertificateEntry keyStoreEntry = new KeyStore.TrustedCertificateEntry(trustedCert);
              keyStore.setEntry(keyEntryName, keyStoreEntry, null);
              keyStore.store(new FileOutputStream(keyStoreFileName), keyStorePassword.toCharArray());
          }
      
    • void addPrivateKey(…) : method adding a password-protected private key to the keystore. The PrivateKeyEntry entry is password-protected.
          public void addPrivateKey(String keyEntryName, String keyEntryPassword, PrivateKey privateKey, Certificate[] certificatesChain) throws Exception {
              KeyStore.PrivateKeyEntry keyStoreEntry = new KeyStore.PrivateKeyEntry(privateKey, certificatesChain);
              KeyStore.PasswordProtection keyPassword = new KeyStore.PasswordProtection(keyEntryPassword.toCharArray());
              keyStore.setEntry(keyEntryName, keyStoreEntry, keyPassword);
              keyStore.store(new FileOutputStream(keyStoreFileName), keyStorePassword.toCharArray());
          }
      
    • SecretKey getSecretKey(…) : method allowing the getting a secret key from keystore. The entry and keystore are protected by different passwords.
          public SecretKey getSecretKey(String keyEntryName, String keyEntryPassword) throws Exception {
      		if (StringUtils.isEmpty(keyEntryName)) {
      			throw new IllegalArgumentException("Key entry name should be provided");
      		}
              KeyStore.PasswordProtection keyPassword = new KeyStore.PasswordProtection(keyEntryPassword.toCharArray());
              KeyStore.Entry entry = keyStore.getEntry(keyEntryName, keyPassword);
              if(entry==null){
                  return null;
              } else {
                  SecretKey keyFound = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
                  return keyFound;
              }
          }
      
    • PrivateKey getPrivateKey(…) : method allowing the getting a private key from keystore. The entry and keystore are protected by different passwords.
          public PrivateKey getPrivateKey(String keyEntryName, final String keyEntryPassword) throws Exception {
      		if (StringUtils.isEmpty(keyEntryName)) {
      			throw new IllegalArgumentException("Key entry name should be provided");
      		}
              KeyStore.PasswordProtection keyPassword = new KeyStore.PasswordProtection(keyEntryPassword.toCharArray());
              KeyStore.Entry entry = keyStore.getEntry(keyEntryName, keyPassword);
              if(entry==null){
                  return null;
              } else {
              	PrivateKey keyFound = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
                  return keyFound;
              }
      	}
      
    • Certificate getCertificate(…) : method allowing the getting a certificate from keystore. The entry TrustedCertificateEntry is NOT protected but the keystore is protected by password.
          public Certificate getCertificate(String keyEntryName) throws Exception {
      		if (StringUtils.isEmpty(keyEntryName)) {
      			throw new IllegalArgumentException("Key entry name should be provided");
      		}
              KeyStore.Entry entry = keyStore.getEntry(keyEntryName, null);
              if(entry==null){
                  return null;
              } else {
              	Certificate certificatFound = ((KeyStore.TrustedCertificateEntry) entry).getTrustedCertificate();
                  if (certificatFound == null) {
                      throw new IllegalArgumentException(String.format("No certificate found for alias '%s'", keyEntryName));
                  }
                  return certificatFound;
              }
          }
      
    • PublicKey getPublicKeyOfCertificate(…) : method allowing the getting a public key contained in certificate from keystore. The entry TrustedCertificateEntry is NOT protected but the keystore is protected by password.
          public PublicKey getPublicKeyOfCertificate(String keyEntryName) throws Exception {
      		if (StringUtils.isEmpty(keyEntryName)) {
      			throw new IllegalArgumentException("Key entry name should be provided");
      		}
              KeyStore.Entry entry = keyStore.getEntry(keyEntryName, null);
              if(entry==null){
                  return null;
              } else {
              	Certificate certificatFound = ((KeyStore.TrustedCertificateEntry) entry).getTrustedCertificate();
                  if (certificatFound == null) {
                      throw new IllegalArgumentException(String.format("No certificate found for alias '%s'", keyEntryName));
                  }
                  return certificatFound.getPublicKey();
              }
          }
      
    • boolean hasSecretKey(…) : method checking if a secret key is stored in keystore. The entry and keystore are protected by different passwords.
          public boolean hasSecretKey(String keyEntryName, String keyEntryPassword, byte[] keyValue) throws Exception {
              KeyStoreManagement keyStoreManagement = new KeyStoreManagement(this.keyStoreFileName, this.keyStorePassword);
              SecretKey tmp = keyStoreManagement.getSecretKey(keyEntryName, keyEntryPassword);
              if(tmp == null){
                  return false;
              } else {
                  return new String(keyValue).equals(new String(tmp.getEncoded()));
              }
          }
      
    • boolean hasPrivateKey(…) : method checking if private key is stored in keystore. The entry and keystore are protected by different passwords.
          public boolean hasPrivateKey(String keyEntryName, String keyEntryPassword, byte[] keyValue) throws Exception {
              KeyStoreManagement keyStoreManagement = new KeyStoreManagement(this.keyStoreFileName, this.keyStorePassword);
              PrivateKey tmp = keyStoreManagement.getPrivateKey(keyEntryName, keyEntryPassword);
              if(tmp == null){
                  return false;
              } else {
                  return new String(keyValue).equals(new String(tmp.getEncoded()));
              }
          }
      
    • boolean hasCertificate(…) : method checking if certificate is stored in keystore. ONLY the keystore is protected by password.
          public boolean hasCertificate(String keyEntryName, byte[] certificateValue) throws Exception {
              KeyStoreManagement keyStoreManagement = new KeyStoreManagement(this.keyStoreFileName, this.keyStorePassword);
              Certificate tmp = keyStoreManagement.getCertificate(keyEntryName);
              if(tmp == null){
                  return false;
              } else {
                  return new String(certificateValue).equals(new String(tmp.getEncoded()));
              }
          }
      
    • boolean hasPublicKeyOfCertificate(…) : method checking if public key containd in a certificate is stored in keystore. ONLY the keystore is protected by password.
          public boolean hasPublicKeyOfCertificate(String keyEntryName, byte[] keyValue) throws Exception {
              KeyStoreManagement keyStoreManagement = new KeyStoreManagement(this.keyStoreFileName, this.keyStorePassword);
              Certificate tmp = keyStoreManagement.getCertificate(keyEntryName);
              if(tmp == null || tmp.getPublicKey()==null){
                  return false;
              } else {
              	PublicKey keyTmp = tmp.getPublicKey();
                  return new String(keyValue).equals(new String(keyTmp.getEncoded()));
              }
          }
      

     
     

  3. Example : Class Test of JCEKS Keystore Management

    …The information concerning the keystore (filename, password-protection) and the contained keys (name, password-protected) are stored in a properties file ConfigKeystore.properties
    keystore_name=myHuoKeystore.keystore
    keystore_pwd=123java.LU321
    #
    keystore_secretkey1_entry_name=KeyStoReP@sswd4SecrEtKEy1eNtry
    keystore_secretkey1_entry_pwd=KeYp@sswdStoreSecrEtEntry1Pwd
    keystore_secretkey2_entry_name=KeyStoReP@sswd4SecrEtKEy2eNtry
    keystore_secretkey2_entry_pwd=KeYp@sswdStoreSecrEtEntry2Pwd
    #
    keystore_privatekey_entry_name=KeyStoReP@sswd4PrivAteKEyeNtry
    keystore_privatekey_entry_pwd=KeYp@sswdStorePrivATeEntryPwd
    #
    keystore_certificate_entry_name=KeyStoReP@sswd4CertiFicaTeeNtry

        public static Properties getProperties() throws Exception {
            Properties prop = new Properties();
            String filename = System.getProperty("user.dir") + "/resources/ConfigKeystore.properties";
            prop.load(new FileReader(new File(filename).getPath()));
            return prop;
        }
    

     
     
    …In the JDK1.7.0_79, the class sun.security.x509.X500Signer has been removed, so, for our tests, we will create this simple package with corresponding package:

    package sun.security.x509;
    
    import java.security.Signature;
    import java.security.SignatureException;
    import java.security.Signer;
    import java.security.NoSuchAlgorithmException;
    
    /**
     * This class provides a binding between a Signature object and an
     * authenticated X.500 name (from an X.509 certificate chain), which
     * is needed in many public key signing applications.
     */
    public final class X500Signer extends Signer
    {
        private static final long serialVersionUID = -8609982645394364834L;
    
        /**
         * Called for each chunk of the data being signed.  That
         * is, you can present the data in many chunks, so that
         * it doesn't need to be in a single sequential buffer.
         *
         * @param buf buffer holding the next chunk of the data to be signed
         * @param offset starting point of to-be-signed data
         * @param len how many bytes of data are to be signed
         * @exception SignatureException on errors.
         */
        public void update(byte buf[], int offset, int len)
        throws SignatureException {
            sig.update (buf, offset, len);
        }
    
        /**
         * Produces the signature for the data processed by update().
         *
         * @exception SignatureException on errors.
         */
        public byte[] sign() throws SignatureException {
            return sig.sign();
        }
    
        /**
         * Returns the algorithm used to sign.
         */
        public AlgorithmId  getAlgorithmId() {
            return algid;
        }
    
        /**
         * Returns the name of the signing agent.
         */
        public X500Name     getSigner() {
            return agent;
        }
    
        /*
         * Constructs a binding between a signature and an X500 name
         * from an X.509 certificate.
         */
        // package private  ----hmmmmm ?????
        public X500Signer(Signature sig, X500Name agent) {
            if (sig == null || agent == null)
                throw new IllegalArgumentException ("null parameter");
    
            this.sig = sig;
            this.agent = agent;
    
            try {
              this.algid = AlgorithmId.getAlgorithmId(sig.getAlgorithm());
    
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("internal error! " + e.getMessage());
            }
        }
    
        private Signature   sig;
        private X500Name    agent;          // XXX should be X509CertChain
        private AlgorithmId algid;
    }
    

     
    This class is used during the generation of a self-signed certificate X509:

        public static X509Certificate getSelfCertificate (X500Name myname, Date firstDate, long validity, String sigAlg, PrivateKey privateKey, PublicKey publicKey) throws Exception{
            X509CertImpl cert;
            //This class X500Signer has been created in our project in order to compensate the lack of used JDK/JRE. 
            X500Signer issuer = null;
            {
               	Signature signature = Signature.getInstance(sigAlg);
               	signature.initSign (privateKey);
               	issuer = new X500Signer (signature, myname);
            }
    
            Date lastDate = new Date ();
            lastDate.setTime (firstDate.getTime () + validity * 1000);
    
            CertificateValidity interval = new CertificateValidity(firstDate,lastDate);
    
            X509CertInfo info = new X509CertInfo();
            // Add all mandatory attributes
            info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
            info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int)(firstDate.getTime()/1000)));
            AlgorithmId algID = issuer.getAlgorithmId();
            info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algID));
            info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(myname));
            info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
            info.set(X509CertInfo.VALIDITY, interval);
            info.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuer.getSigner()));
    
            if (System.getProperty("sun.security.internal.keytool.skid") != null) {
            	CertificateExtensions ext = new CertificateExtensions();
                ext.set(SubjectKeyIdentifierExtension.NAME, new SubjectKeyIdentifierExtension(new KeyIdentifier(publicKey).getIdentifier()));
                info.set(X509CertInfo.EXTENSIONS, ext);
            }
    
            cert = new X509CertImpl(info);
            cert.sign(privateKey, sigAlg);
            return (X509Certificate)cert;
        }
    

     
     
    …First we need a keystore:

    // Generate the KeyStore
    KeyStoreManagement keyStoreManagement = new KeyStoreManagement(System.getProperty("user.dir") + "/resources/" + prop.getProperty("keystore_name"), prop.getProperty("keystore_pwd"));
    

     
     
    TEST 1 : SECRET KEY 1 : PBE-MD5-DES

    System.out.println("########################## SECRET KEY 1 : PBE-MD5-DES");
    // Generate a SecretKey
    SecretKey secretKey = null;
    {
    	String encryptionType="PBEWithMD5AndDES";
    	KeySpec keySpec= new PBEKeySpec("HUO12JavDotLuX12".toCharArray());
    	secretKey = SecretKeyFactory.getInstance(encryptionType).generateSecret(keySpec);
    }
    
    
    // Add SecretKey to KeyStore
    System.out.println("#### Add SecretKey to KeyStore : entry="+prop.getProperty("keystore_secretkey1_entry_name")+" and password="+prop.getProperty("keystore_secretkey1_entry_pwd"));
    keyStoreManagement.addSecretKey(prop.getProperty("keystore_secretkey1_entry_name"), prop.getProperty("keystore_secretkey1_entry_pwd"), secretKey);
    
    
    // Check the presence of SecretKey in KeyStore
    System.out.println("#### Check the presence of SecretKey in KeyStore : entry="+prop.getProperty("keystore_secretkey1_entry_name")+" and password="+prop.getProperty("keystore_secretkey1_entry_pwd"));
    boolean isFound = keyStoreManagement.hasSecretKey(prop.getProperty("keystore_secretkey1_entry_name"), prop.getProperty("keystore_secretkey1_entry_pwd"), secretKey.getEncoded());
    System.out.println("=>"+isFound);
    
    
    // Get SecretKey from KeyStore
    System.out.println("#### Get SecretKey from KeyStore : entry="+prop.getProperty("keystore_secretkey1_entry_name")+" and password="+prop.getProperty("keystore_secretkey1_entry_pwd"));
    SecretKey secretKeyExtract = keyStoreManagement.getSecretKey(prop.getProperty("keystore_secretkey1_entry_name"), prop.getProperty("keystore_secretkey1_entry_pwd"));
    System.out.println("#### Check the value of original SecretKey and the extracted SecretKey : ");
    System.out.println("=>"+new String(secretKeyExtract.getEncoded()).equals(new String(secretKey.getEncoded())));
    

    The outputs should be:
    ########################## SECRET KEY 1 : PBE-MD5-DES
    #### Add SecretKey to KeyStore : entry=KeyStoReP@sswd4SecrEtKEy1eNtry and password=KeYp@sswdStoreSecrEtEntry1Pwd
    #### Check the presence of SecretKey in KeyStore : entry=KeyStoReP@sswd4SecrEtKEy1eNtry and password=KeYp@sswdStoreSecrEtEntry1Pwd
    =>true
    #### Get SecretKey from KeyStore : entry=KeyStoReP@sswd4SecrEtKEy1eNtry and password=KeYp@sswdStoreSecrEtEntry1Pwd
    #### Check the value of original SecretKey and the extracted SecretKey :
    =>true

     
     
    TEST 2 : SECRET KEY 2 : AES 128 bytes

    System.out.println("########################## SECRET KEY 2 : AES 128 bytes");
    // Generate a SecretKey
    SecretKey secretKey = null;
    {
    	KeyGenerator keyGenAes = KeyGenerator.getInstance("AES");
    	keyGenAes.init(128);
    	secretKey = keyGenAes.generateKey();
    }
    
    
    // Add SecretKey to KeyStore
    System.out.println("#### Add SecretKey to KeyStore : entry="+prop.getProperty("keystore_secretkey2_entry_name")+" and password="+prop.getProperty("keystore_secretkey2_entry_pwd"));
    keyStoreManagement.addSecretKey(prop.getProperty("keystore_secretkey2_entry_name"), prop.getProperty("keystore_secretkey2_entry_pwd"), secretKey);
        	        
    
    // Check the presence of SecretKey in KeyStore
    System.out.println("#### Check the presence of SecretKey in KeyStore : entry="+prop.getProperty("keystore_secretkey2_entry_name")+" and password="+prop.getProperty("keystore_secretkey2_entry_pwd"));
    boolean isFound = keyStoreManagement.hasSecretKey(prop.getProperty("keystore_secretkey2_entry_name"), prop.getProperty("keystore_secretkey2_entry_pwd"), secretKey.getEncoded());
    System.out.println("=>"+isFound);
        	        
    
    // Get SecretKey from KeyStore
    System.out.println("#### Get SecretKey from KeyStore : entry="+prop.getProperty("keystore_secretkey2_entry_name")+" and password="+prop.getProperty("keystore_secretkey2_entry_pwd"));
    SecretKey secretKeyExtract = keyStoreManagement.getSecretKey(prop.getProperty("keystore_secretkey2_entry_name"), prop.getProperty("keystore_secretkey2_entry_pwd"));
    System.out.println("#### Check the value of original SecretKey and the extracted SecretKey : ");
    System.out.println("=>"+new String(secretKeyExtract.getEncoded()).equals(new String(secretKey.getEncoded())));
    

    The outputs should be:
    ########################## SECRET KEY 2 : AES 128 bytes
    #### Add SecretKey to KeyStore : entry=KeyStoReP@sswd4SecrEtKEy2eNtry and password=KeYp@sswdStoreSecrEtEntry2Pwd
    #### Check the presence of SecretKey in KeyStore : entry=KeyStoReP@sswd4SecrEtKEy2eNtry and password=KeYp@sswdStoreSecrEtEntry2Pwd
    =>true
    #### Get SecretKey from KeyStore : entry=KeyStoReP@sswd4SecrEtKEy2eNtry and password=KeYp@sswdStoreSecrEtEntry2Pwd
    #### Check the value of original SecretKey and the extracted SecretKey :
    =>true

     
     
    TEST 3 : PRIVATE and PUBLIC KEY – RSA 1024

    System.out.println("########################## PRIVATE and PUBLIC KEY - RSA 1024");
    // Generate a PrivateKey and PublicKey
    PrivateKey privateKey = null;
    PublicKey publicKey = null;
    X509Certificate certificate = null;
    PublicKey publicKeyInCertificate = null;
    {
    	// METHOD 1 : Use of JAVA classes
    	System.out.println("#### Generation of PrivateKey and PublicKey RSA 1024 via the use of JAVA classes");
            KeyPairGenerator keyGenRsa = KeyPairGenerator.getInstance("RSA");
    	String signatureAlgorithm = "SHA1WithRSA";
            keyGenRsa.initialize(1024);
            KeyPair keyPair = keyGenRsa.genKeyPair();
            publicKey = keyPair.getPublic();
            privateKey = keyPair.getPrivate();
            //Generate self signed certificate
            System.out.println("#### Generation of self signed certificate with previous PrivateKey and PublicKey RSA 1024");
            certificate = getSelfCertificate(new X500Name("CN=ROOT"), new Date(), (long)365*24*3600, signatureAlgorithm, privateKey, publicKey);
            publicKeyInCertificate = certificate.getPublicKey();
        	            
        	// METHOD 2 : Use of CertAndKeyGen class allowing the creation of self-signed X.509 certificates as well as PKCS 10 based certificate signing requests.
            // Creates a CertAndKeyGen object for a particular key type, signature algorithm, and provider.
            // 		o param keyType type of key, e.g. "RSA", "DSA"
            // 		o param sigAlg name of the signature algorithm, e.g. "MD5WithRSA", "MD2WithRSA", "SHAwithDSA".
            // 		o param providerName name of the provider
            /*CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
    	keyGen.generate(1024);
    	//Generate self signed certificate
    	publicKey = keyGen.getPublicKey();
    	privateKey = keyGen.getPrivateKey();
    	certificate = keyGen.getSelfCertificate(new X500Name("CN=ROOT"), (long)365*24*3600);
    	publicKeyInCertificate = certificate.getPublicKey();
    	System.out.println(new String(publicKey.getEncoded()).equals(new String(publicKeyInCertificate.getEncoded())));*/
    }
    System.out.println("#### Check the value of original PublicKey and the PublicKey insided the Certificate: ");
    System.out.println("=>"+new String(publicKey.getEncoded()).equals(new String(publicKeyInCertificate.getEncoded())));
    
    
    System.out.println("#### Creation of Certificate Chain with the previous Certificate");
    X509Certificate[] certificatesChain = new X509Certificate[1];
    certificatesChain[0]= certificate;
    
    
    // Add PrivateKey to KeyStore
    System.out.println("#### Add PrivateKey to KeyStore : entry="+prop.getProperty("keystore_privatekey_entry_name")+" and password="+prop.getProperty("keystore_privatekey_entry_pwd"));
    keyStoreManagement.addPrivateKey(prop.getProperty("keystore_privatekey_entry_name"), prop.getProperty("keystore_privatekey_entry_pwd"), privateKey, certificatesChain);
    
    
    // Add Certificate to KeyStore
    // java.security.KeyStoreException: trusted certificate entries are not password-protected
    System.out.println("#### Add Certificate to KeyStore : entry="+prop.getProperty("keystore_certificate_entry_name"));
    keyStoreManagement.addCertificate(prop.getProperty("keystore_certificate_entry_name"), certificate);
    
    
    // Check the presence of PrivateKey in KeyStore
    System.out.println("#### Check the presence of PrivateKey in KeyStore : entry="+prop.getProperty("keystore_privatekey_entry_name")+" and password="+prop.getProperty("keystore_privatekey_entry_pwd"));
    boolean isFound = keyStoreManagement.hasPrivateKey(prop.getProperty("keystore_privatekey_entry_name"), prop.getProperty("keystore_privatekey_entry_pwd"), privateKey.getEncoded());
    System.out.println("=>"+isFound);
    		        
    
    // Get PrivateKey from KeyStore
    System.out.println("#### Get PrivateKey from KeyStore : entry="+prop.getProperty("keystore_privatekey_entry_name")+" and password="+prop.getProperty("keystore_privatekey_entry_pwd"));
    PrivateKey privateKeyExtract = keyStoreManagement.getPrivateKey(prop.getProperty("keystore_privatekey_entry_name"), prop.getProperty("keystore_privatekey_entry_pwd"));
    System.out.println("#### Check the value of original PrivateKey and the extracted PrivateKey : ");
    System.out.println("=>"+new String(privateKeyExtract.getEncoded()).equals(new String(privateKey.getEncoded())));
    
    
    // Check the presence of Certificate in KeyStore
    System.out.println("#### Check the presence of Certificate in KeyStore : entry="+prop.getProperty("keystore_certificate_entry_name"));
    isFound = keyStoreManagement.hasCertificate(prop.getProperty("keystore_certificate_entry_name"), certificate.getEncoded());
    System.out.println("=>"+isFound);
    		        
    
    // Check the presence of PublicKey in KeyStore
    System.out.println("#### Check the presence of PublicKey in KeyStore : entry="+prop.getProperty("keystore_certificate_entry_name"));
    isFound = keyStoreManagement.hasPublicKeyOfCertificate(prop.getProperty("keystore_certificate_entry_name"), publicKey.getEncoded());
    System.out.println("=>"+isFound);
    
    // Get Certificate from KeyStore
    System.out.println("#### Get Certificate from KeyStore : entry="+prop.getProperty("keystore_certificate_entry_name"));
    Certificate certificateExtract = keyStoreManagement.getCertificate(prop.getProperty("keystore_certificate_entry_name"));
    System.out.println("#### Check the value of original Certificate and the extracted Certificate : ");
    System.out.println("=>"+new String(certificateExtract.getEncoded()).equals(new String(certificate.getEncoded())));
    
    // Get PublicKey from KeyStore
    System.out.println("#### Get PublicKey from KeyStore : entry="+prop.getProperty("keystore_certificate_entry_name"));
    PublicKey publicKeyExtract = keyStoreManagement.getPublicKeyOfCertificate(prop.getProperty("keystore_certificate_entry_name"));
    System.out.println("#### Check the value of original PublicKey and the extracted PublicKey : ");
    System.out.println("=>"+new String(publicKeyExtract.getEncoded()).equals(new String(publicKey.getEncoded())));
    

    The outputs should be:

    ########################## PRIVATE and PUBLIC KEY - RSA 1024
    #### Generation of PrivateKey and PublicKey RSA 1024 via the use of JAVA classes
    #### Generation of self signed certificate with previous PrivateKey and PublicKey RSA 1024
    #### Check the value of original PublicKey and the PublicKey insided the Certificate:
    =>true
    #### Creation of Certificate Chain with the previous Certificate
    #### Add PrivateKey to KeyStore : entry=KeyStoReP@sswd4PrivAteKEyeNtry and password=KeYp@sswdStorePrivATeEntryPwd
    #### Add Certificate to KeyStore : entry=KeyStoReP@sswd4CertiFicaTeeNtry
    #### Check the presence of PrivateKey in KeyStore : entry=KeyStoReP@sswd4PrivAteKEyeNtry and password=KeYp@sswdStorePrivATeEntryPwd
    =>true
    #### Get PrivateKey from KeyStore : entry=KeyStoReP@sswd4PrivAteKEyeNtry and password=KeYp@sswdStorePrivATeEntryPwd
    #### Check the value of original PrivateKey and the extracted PrivateKey :
    =>true
    #### Check the presence of Certificate in KeyStore : entry=KeyStoReP@sswd4CertiFicaTeeNtry
    =>true
    #### Check the presence of PublicKey in KeyStore : entry=KeyStoReP@sswd4CertiFicaTeeNtry
    =>true
    #### Get Certificate from KeyStore : entry=KeyStoReP@sswd4CertiFicaTeeNtry
    #### Check the value of original Certificate and the extracted Certificate :
    =>true
    #### Get PublicKey from KeyStore : entry=KeyStoReP@sswd4CertiFicaTeeNtry
    #### Check the value of original PublicKey and the extracted PublicKey :
    =>true

     
     

Resources:
https://en.wikipedia.org/wiki/X.509
https://docs.oracle.com/javase/7/docs/api/java/security/cert/Certificate.html
http://www.pixelstech.net/article/index.php?id=1406724116
http://www.pixelstech.net/article/1406726666-Generate-certificate-in-Java—-2
http://www.pixelstech.net/article/1408524957-Generate-cetrificate-in-Java—-3

Sources : keystore.zip

That’s all!!!

Huseyin OZVEREN