Pular para conteúdo

JCA SSL connection

Informações Gerais

Utilização do provider JCA do HSM para estabelecimento de túnel TLS com autenticação mútua (mTLS).

O código é do exemplo da documentação da API Java do HSM.

Este exemplo faz uma conexão com um endpoint da SEFAZ-SP (Secrtaria de Fazenda do Estado se São Paulo) acessivel em 03 de outubro de 2025, mas pode ser utilizado com qualquer host compatível com o padrão.

As configurações do ambiente:

  • SO: Windows 11 Pro (inglês)
  • Command prompt
  • Maven 3.9.1
  • Navegador Chrome: Versão 134.0.6998.166 (Versão oficial) 64 bits
  • Java 21 (instalado, no path e no JAVA_HOME)
  • Firmware do HSM: 5.9.0.0
  • Cliente do HSM: 4.19.0
  • Cliente Java do HSM: 4.19.0 (ou superior)

Requisitos

  1. Conectividade com o HSM (porta TCP 4433).
  2. Serviço do HSM iniciado.
  3. Credenciais da partição do HSM onde será criada ou utilizada a chave privada.
  4. Chave privada, certificado e cadeia do usuário.
  5. Cadeia de certificados do host remoto.

Artefatos

Danger

Siga estritamente as regras de nomenclatura ou os certificados e cadeias nao poderão ser encontados, impossibilitando o estabelecimento do túnel TLS. Veja mais detalhes e opções na documentação da JCA.

Exemplo:

  • Chave privada: o nome é livre. Ex.: teste.
  • Certificado: o nome da chave privada com sufixo _cert. Ex.: teste_cert.
  • Cadeia de certificados: o nome da chave privada com sufixo _chain. Ex.: teste_chain.

Importação de um Arquivo .pfx

Caso não tenha uma chave privada e certificado instalado no HSM, executar os seguintes passos.

  1. Instalar o client do HSM, dispnivel em downloads.
  2. Abrir o programa dinamocon.
  3. Configurar as informações do HSM.
  4. Importar o arquivo PFX que contém a chave privada e o certificado que serão usados para a autenticação mútua.

Neste ponto o HSM terá uma chave privada e um certificado do usuário. Por exemplo: chave privada com nome de teste e certificado com nome de teste_cert.

Exportação da Cadeia do Usuário

Caso não tenha a cadeia de certificados instalada no HSM seguindo a nomenclatura correta siga os seguintes passos.

  1. Abrir o certificate manager. Pode ser executando o seguinte comando.

    certmgr.msc
    
  2. Dar um duplo clique no certificado importado.

  3. Selecionar a aba Caminho de Certificação (Certification Path), e então dar um duplo clique na autoridade certificadora logo acima do certificado importado.

    Selecionar pkcs#7
    Selecionar pkcs#7

  4. Selecionar a aba Detalhes e então clicar em Copiar para arquivo.

    Copiar para arquivo
    Copiar para arquivo

  5. Selecionar Não exportar chave privada.

  6. Selecionar Certificado PKCS#7 (.P7B).

    Selecionar pkcs#7
    Selecionar pkcs#7

  7. Salvar o arquivo .p7b.

Importação da Cadeia do Usuário

  1. No prompt de comando executar o seguinte comando hsmcon <IP> <usuário>. E em seguida inserir a senha.

    Ex.:

    hsmcon 127.0.0.1 master
    

  2. Importar a cadeia de certificados. Selecionar a opção Import, Others e então PKCS#7. Adicionar o nome do arquivo .p7b e em seguida o nome da cadeia, seguindo a nomenclatura.

    Importação de cadeia de certificados no HSM
    Dinamo - 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...
    
  3. Verificar os objetos. No menu principal, escolher a opção de listar objetos List.

    Objeto Tipo Nomenclatura Exemplo
    Chave privada ex. rsa2048 livre teste
    Certificado x.509 nome da chave mais o sufixo _cert teste_cert
    Cadeia de certificados pkcs#7 nome da chave mais o sufixo _chain teste_chain

    Detalhes da nomenclatura podem ser vistos acima ou na documentação da JCA.

    Listagem de objetos no HSM
    Dinamo - 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...
    

Exportação da Cadeia do Host Remoto

Para fazer a autenticação mútua é preciso verificar o host remoto, e para isso precisamos da sua cadeia de certificados.

Uma forma de recuperação, para efeitos didáticos é o mostrado a seguir.

  1. Abrir o navegador e acessar a página de destino (não é preciso se autenticar), clicar em Não seguro e então em certificado.

    Selecionar certificado remoto
    Selecionar certificado remoto

  2. Na janela que abre, clicar em Detalhes, depois em exportar e então salvar em um arquivo.

    Exportar certificado remoto
    Exportar certificado remoto

  3. Abrir o certificado e então executar os passos acima, mas agora para extrarir a cadeia de certificados do host remoto.

Criação do Projeto

  1. Criar projeto padrão.

    mvn archetype:generate -DgroupId=doxy.examples -DartifactId=jcassl -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. Entrar na pasta do projeto.

    cd jcassl
    
  3. Copiar o arquivo de exemplo da documentação da API Java do HSM para a pasta src\main\java\doxy\examples.

    Remover os arquivos:

    • src\main\java\doxy\examples\App.java
    • src\test\java\doxy\examples\AppTest.java
  4. Alterar o POM para o seguinte conteúdo:

    <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>
    
  5. Compilar.

    mvn clean package
    

Execução e Teste de Conexão

Para definir qual HSM será usado pela JCA, iremos utilizar system properties mas outras formas também são aceitas.

  1. Executar o comando da seguinte forma:

    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>`"
    

    Ex.:

    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"
    

    Neste exemplo ele deve mostrar os subjects dos certificados da cadeia e o código html do host remoto.

    Ex.:

    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] ------------------------------------------------------------------------