JCA SSL connection
General Information
Use of the HSM JCAprovider to establish a TLS tunnel with mutual authentication (mTLS).
The code is an example from the HSM Java API documentation.
This example makes a connection to a SEFAZ-SP (São Paulo State Treasury Department) endpoint accessible on October 3, 2025, but can be used with any host compatible with the standard.
Environment settings:
- OS: Windows 11 Pro
- Command prompt
- Maven 3.9.1
- Chrome Browser: Version 134.0.6998.166 (Official version) 64-bit
- Java 21 (installed, in path and JAVA_HOME)
- HSM firmware: 5.9.0.0
- HSM client: 4.19.0
- HSM Java Client: 4.19.0 (or higher)
Requirements
- Connectivity with the HSM (TCP port 4433).
- HSM service started.
- Credentials of the HSM partition where the private key will be created or used.
- Private key, certificate and user chain.
- Certificate chain of the remote host.
Artifacts
Danger
Strictly follow the naming rules or the certificates and chains will not be found, making it impossible to establish the TLS tunnel. See more details and options in the JCA documentation.
Example:
- Private key: the name is free. E.g.:
test
. - Certificate: the name of the private key with suffix
_cert
. E.g.:test_cert
. - Certificate chain: the name of the private key with a
_chain
suffix. E.g.:test_chain
.
Importing a .pfx file
If you do not have a private key and certificate installed in the HSM, perform the following steps.
- Install the HSM client, available in downloads.
- Open the dynamocon program.
- Configure the HSM information.
- Import the PFX file containing the private key and certificate that will be used for mutual authentication.
At this point the HSM will have a private key and a user certificate. For example: private key named test
and certificate named test_cert
.
User Chain Export
If you don't have the certificate chain installed in the HSM with the correct nomenclature, follow these steps.
-
Open the certificate manager. You can do this by running the following command.
certmgr.msc
-
Double-click on the imported certificate.
-
Select theCertification Path tab, then double-click on the certification authority just above the imported certificate.
Select pkcs#7 -
Select the Details tab and then click Copy to file.
Copy to file -
Select Do not export private key.
-
Select Certificate PKCS#7 (.P7B).
Select pkcs#7 -
Save the
.p7b
file.
Importing the User Chain
-
No prompt de comando executar o seguinte comando
hsmcon <IP> <usuário>
. E em seguida inserir a senha.E.g:
hsmcon 127.0.0.1 master
-
Import the certificate chain. Select
Import
,Others
and thenPKCS#7
. Add the name of the.p7b
file and then the name of the chain, following the nomenclature.Importing certificate chains into HSMDinamo - Remote Management Console v. 4.19.0.0 2018 (c) Dinamo Networks HSM 127.0.0.1 e - Engine 5.9.0.0 (DXP) - TCA0000000 - ID master Keys/Objects - Import - Others - PKCS#7 File (local): D:\tmp\examples\jcassl\test.p7b File name (HSM): teste_chain File loaded successfully. Press ENTER key to continue...
-
Check the objects. In the main menu, choose the option to list
List
objects.Object Type Nomenclature Example Private key e.g. rsa2048 free test
Certificate x.509 key name plus suffix _cert
test_cert
Chain of certificates pkcs#7 key name plus _chain
suffixtest_chain
Details of the nomenclature can be seen above or in the JCA documentation.
Listing objects in HSMDinamo - Remote Management Console v. 4.19.0.0 2018 (c) Dinamo Networks HSM 127.0.0.1 e - Engine 5.9.0.0 (DXP) - TCA0000000 - ID master Keys/Objects - List Name Type T E Label ================================================================================ teste rsa2048 n y teste_cert teste_cert x.509 n y teste_cert teste_chain pkcs#7 n y Total of objects: 3 Press ENTER key to continue...
Remote Host Chain Export
To perform mutual authentication, we need to verify the remote host, and for this we need its certificate chain.
A form of recovery, for didactic purposes, is shown below.
-
Open your browser and go to the destination page (you don't need to log in), click on Not secure and then on certificate.
Select remote certificate -
In the window that opens, click on Details, then export and then save to a file.
Export remote certificate -
Open the certificate and then perform the steps above, but now to extract the certificate chain from the remote host.
Project creation
-
Create a standard project.
mvn archetype:generate -DgroupId=doxy.examples -DartifactId=jcassl -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
-
Enter the project folder.
cd jcassl
-
Copy the example file from the HSM Java API documentation to the
src\main\java\doxy\examples
folder.Remove the files:
src\main\java\doxy\examples\App.java
src\test\java\doxy\examples\AppTest.java
-
Change the POM to the following content:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>doxy.examples</groupId> <artifactId>jcassl</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>JCASSL</name> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> <dependencies> <!-- Dinamo HSM SDK (external, not bundled) --> <dependency> <groupId>io.dinamonetworks.sdk</groupId> <artifactId>dinamo-hsm</artifactId> <version>4.19.0</version> </dependency> </dependencies> <build> <plugins> <!-- Compiler plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> </configuration> </plugin> <!-- Jar plugin to define main class --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>doxy.examples.JCASSL</mainClass> </manifest> </archive> </configuration> </plugin> <!-- Exec plugin for easy run --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> </plugin> </plugins> </build> </project>
-
Compile.
mvn clean package
Connection Execution and Testing
To define which HSM will be used by the JCA, we will use system properties
but other forms are also acceptable.
-
Execute the command as follows:
mvn exec:java -Dexec.mainClass="doxy.examples.JCASSL" -Ddinamo.hsm.jca.ip=`<IP DO HSM>` -Ddinamo.hsm.jca.user=`<USUÁRIO DO HSM>` -Ddinamo.hsm.jca.pwd=`<SENHA DO USUÁRIO>` -Dexec.args="`<URL DE DESTINO>` `<ARQUIVO DA CADEIA DO HOST REMOTO> ` `<ID DA CHAVE PRIVADA>`"
E.g:
mvn exec:java -Dexec.mainClass="doxy.examples.JCASSL" -Ddinamo.hsm.jca.ip=127.0.0.1 -Ddinamo.hsm.jca.user=master -Ddinamo.hsm.jca.pwd=12345678 -Dexec.args="https://nfe.fazenda.sp.gov.br/ws/nfestatusservico4.asmx D:\tmp\examples\jcassl\sefaz-sp.p7b teste"
In this example it should show the subjects of the chain certificates and the html code of the remote host.
E.g:
mvn exec:java -Dexec.mainClass="doxy.examples.JCASSL" -Ddinamo.hsm.jca.ip=127.0.0.1 -Ddinamo.hsm.jca.user=master -Ddinamo.hsm.jca.pwd=12345678 -Dexec.args="https://nfe.fazenda.sp.gov.br/ws/nfestatusservico4.asmx D:\tmp\examples\jcassl\sefaz-sp.p7b teste"
[INFO] Scanning for projects... [INFO] [INFO] ------------------------< doxy.examples:jcassl >------------------------ [INFO] Building JCASSL 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- exec:3.1.0:java (default-cli) @ jcassl --- Host chain(received from host): [0] Subject: OID.1.3.6.1.4.1.311.60.2.1.3=BR, OID.2.5.4.15=Government Entity, CN=nfe.fazenda.sp.gov.br, SERIALNUMBER=46377222000129, L=Abadia de Goias, ST=GO, O=SECRETARIA DA FAZENDA E PLANEJAMENTO, C=BR Issuer: CN=AC SOLUTI SSL EV G4, OU=Autoridade Certificadora Raiz Brasileira v10, O=ICP-Brasil, C=BR [1] Subject: CN=AC SOLUTI SSL EV G4, OU=Autoridade Certificadora Raiz Brasileira v10, O=ICP-Brasil, C=BR Issuer: CN=Autoridade Certificadora Raiz Brasileira v10, OU=Instituto Nacional de Tecnologia da Informacao - ITI, O=ICP-Brasil, C=BR URL content: <html> <head><link rel="alternate" type="text/xml" href="/ws/nfestatusservico4.asmx?disco" /> <style type="text/css"> ... </style> <title> NFeStatusServico4 Web Service </title></head> <body> <div id="content"> <p class="heading1">NFeStatusServico4</p><br> <span> <p class="intro">Serviço destinado à consulta do status do serviço prestado pelo Portal da Secretaria de Fazenda Estadual.</p> </span> <span> <p class="intro">The following operations are supported. For a formal definition, please review the <a href="nfestatusservico4.asmx?WSDL">Service Description</a>. </p> <ul> <li> <a href="nfestatusservico4.asmx?op=nfeStatusServicoNF">nfeStatusServicoNF</a> <span> <br>Consulta Status do Serviço </span> </li> <p> </ul> </span> <span> </span> </body> </html> [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.266 s [INFO] Finished at: 2025-10-03T20:31:50-03:00 [INFO] ------------------------------------------------------------------------