Skip to content

Instantly share code, notes, and snippets.

@tkaczenko
Last active March 25, 2024 14:26
Show Gist options
  • Save tkaczenko/2175995f3cd4733209cedce8ddee6f05 to your computer and use it in GitHub Desktop.
Save tkaczenko/2175995f3cd4733209cedce8ddee6f05 to your computer and use it in GitHub Desktop.
SSL certificates in Java

SSL certificates in Java

How to setup SSL certificate in Java to establish secure connection (HTTPS etc.)?

  1. Get the SSL certificate (public key, ssl.crt) to the resource
    • Download it (ssl.crt) via your browser. For example, you can use this article
    • Download it (ssl.crt) with openssl
    openssl s_client -showcerts -connect secure.veris.net:443 </dev/null | sed -n -e '/-.BEGIN/,/-.END/ p' > ssl.crt
    • Ask the integration partner which you'll connect to
  2. Optional. Get the private key if you're going to provide the secured endpoint in Java (for example, somebody will connect to it with HTTPS)
    • Extract public key
    openssl pkcs12 -in example_com.pfx -clcerts -nokeys -out certificate.crt
    • Extract private key
    openssl pkcs12 -in example_com.pfx -nodes -nocerts -out privatekey.key 
  3. Add public key and private key (if it's provided) to .pkcs12 file using the next command. -legacy here is required due to java 1.8
    openssl pkcs12 -export -in ssl.crt -inkey private.key -out store.p12 -name resource -legacy
    • Don't forget the typed password
  4. Import .p12 file into the Java keystore with the next command
    • Check that you're using the same Java version in terminal which you're using to run the application: java -version
    • the command
    keytool -importkeystore -srckeystore store.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype pkcs12
    • enter the passwords
  5. Use the next command to check that you’ve got the certificate in the keystore
    keytool -list -v -keystore keystore.jks

Additionally, you can use the next Python script to do the same or update it according to your needs

from argparse import ArgumentParser
from dataclasses import dataclass
import logging
import os
import subprocess
import sys
from typing import Optional


@dataclass
class Params:
    private_key_path: str
    public_key_path: str
    keystore_path: str
    keystore_pass: str
    intermediate_p12: Optional[str] = 'keystore.p12'
    alias: Optional[str] = 'public'


def logger() -> None:
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
    logger.addHandler(handler)


def parser() -> ArgumentParser:
    parser = ArgumentParser(
        description="""Download public key for the resource and import private and public key into the keystore."""
    )
    parser.add_argument(
        '--private_key', help='Private key for the resource', required=True, type=str
    )
    parser.add_argument(
        '--public_key', help='Public key for the resource. If it''s not specified, then it would be downloaded', type=str
    )
    parser.add_argument(
        '--keystore', help='Keystore for the resource', type=str
    )
    parser.add_argument(
        '--keystore_pass', help='Keystore password for the resource', type=str
    )
    return parser


def create_intermediate_store():
    subprocess.call(
        "openssl pkcs12 -export "
        f"-in {params.public_key_path} -inkey {params.private_key_path} "
        f"-out {params.intermediate_p12} "
        f"-password pass:{params.keystore_pass} "
        f"-name {params.alias} -legacy",
        shell=True
    )
    logging.info(f"{params.intermediate_p12} has been created")


def import_in_keystore():
    subprocess.call(
        f"keytool -importkeystore -srckeystore {params.intermediate_p12} -srcstoretype pkcs12 -srcstorepass {params.keystore_pass} "
        f"-destkeystore {params.keystore_path} -deststoretype pkcs12 -deststorepass {params.keystore_pass}",
        shell=True
    )


def check_java():
    java_version = subprocess.check_output(
        'java -version', shell=True, stderr=subprocess.STDOUT).decode().split("\r")[0]
    if '1.8' not in java_version:
        logging.error(
            f'Used java version isn''t 1.8. Pls, change default java version')
        sys.exit(1)
    logging.info(java_version)


def cleanup(params: Params):
    os.remove(params.intermediate_p12)
    os.remove(params.private_key_path)


if __name__ == "__main__":
    logger()
    parser = parser()
    args = parser.parse_args()
    params = Params(
        private_key_path=args.private_key,
        public_key_path=args.public_key,
        keystore_path=args.keystore,
        keystore_pass=args.keystore_pass
    )

    create_intermediate_store()
    check_java()
    import_in_keystore()

    cleanup(params)
from argparse import ArgumentParser
from dataclasses import dataclass
import logging
import os
import subprocess
import sys
from typing import Optional
@dataclass
class Params:
private_key_path: str
public_key_path: str
keystore_path: str
keystore_pass: str
intermediate_p12: Optional[str] = 'keystore.p12'
alias: Optional[str] = 'public'
def logger() -> None:
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)
def parser() -> ArgumentParser:
parser = ArgumentParser(
description="""Download public key for the resource and import private and public key into the keystore."""
)
parser.add_argument(
'--private_key', help='Private key for the resource', required=True, type=str
)
parser.add_argument(
'--public_key', help='Public key for the resource. If it''s not specified, then it would be downloaded', type=str
)
parser.add_argument(
'--keystore', help='Keystore for the resource', type=str
)
parser.add_argument(
'--keystore_pass', help='Keystore password for the resource', type=str
)
return parser
def create_intermediate_store():
subprocess.call(
"openssl pkcs12 -export "
f"-in {params.public_key_path} -inkey {params.private_key_path} "
f"-out {params.intermediate_p12} "
f"-password pass:{params.keystore_pass} "
f"-name {params.alias} -legacy",
shell=True
)
logging.info(f"{params.intermediate_p12} has been created")
def import_in_keystore():
subprocess.call(
f"keytool -importkeystore -srckeystore {params.intermediate_p12} -srcstoretype pkcs12 -srcstorepass {params.keystore_pass} "
f"-destkeystore {params.keystore_path} -deststoretype pkcs12 -deststorepass {params.keystore_pass}",
shell=True
)
def check_java():
java_version = subprocess.check_output(
'java -version', shell=True, stderr=subprocess.STDOUT).decode().split("\r")[0]
if '1.8' not in java_version:
logging.error(
f'Used java version isn''t 1.8. Pls, change default java version')
sys.exit(1)
logging.info(java_version)
def cleanup(params: Params):
os.remove(params.intermediate_p12)
os.remove(params.private_key_path)
if __name__ == "__main__":
logger()
parser = parser()
args = parser.parse_args()
params = Params(
private_key_path=args.private_key,
public_key_path=args.public_key,
keystore_path=args.keystore,
keystore_pass=args.keystore_pass
)
create_intermediate_store()
check_java()
import_in_keystore()
cleanup(params)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment