Ir para o conteúdo

Configurar Certificado SSL Corporativo

Este guia mostra como configurar certificados SSL em ambientes com proxy de inspeção SSL (SSL Inspection / MITM), cobrindo aplicações Java (Wizard, BotRunner, BotStudio) e Python (requests).

Contexto

Ambientes corporativos com SSL Inspection (proxy MITM) interceptam conexões HTTPS e substituem o certificado original do servidor por um certificado emitido por uma CA interna da empresa. Isso faz com que aplicações Java e Python rejeitem a conexão, pois não reconhecem essa CA.

Esse comportamento geralmente resulta em erros de SSL ao utilizar ferramentas como o BotCity Runner, normalmente algo como PKIX path building failed ou unable to find valid certification path to requested target.

Uma possível solução para esse cenário é registrar o certificado raiz da CA interna nos respectivos truststores de cada tecnologia.

Pré-requisitos

  • Certificado raiz da CA interna da empresa (arquivo .crt, .cer ou .pem), fornecido pelo time de infraestrutura/segurança.

    Se for necessário extrair, você pode usar o navegador: acesse o servidor de destino pela máquina corporativa, clique no cadeado, exporte a cadeia de certificados e identifique o certificado raiz (o que está no topo da cadeia e é auto-assinado).

  • Java (JDK/JRE) utilizado para executar as aplicações.

    Nesse caso, é preciso saber qual Java está sendo utilizado para a execução das ferramentas (Runner): se é o Java incluído na instalação do SDK ou se está sendo usado o Java da instalação do sistema.

  • Python com o pacote certifi instalado (pip install --upgrade certifi).

Configurar para Java

1. Identificar o cacerts da JVM

O cacerts é o truststore padrão do Java. Sua localização depende da versão e do Java que está sendo utilizado:

# cacerts no Java 9+
# $JAVA_HOME\lib\security\cacerts

# cacerts no Java 8
# $JAVA_HOME\jre\lib\security\cacerts

# Comando que pode auxiliar a identificar o Java instalado
# java -version

Se o Java usado para a execução das ferramentas é o Java incluído no BotCity Studio SDK, o caminho para o arquivo cacerts deve ser algo como:

"<BOTCITY_SDK_PATH>\win32\java\lib\security\cacerts"

Confirme que o arquivo existe:

Test-Path "<PATH_JAVA>\lib\security\cacerts"

2. Listar os certificados existentes (opcional)

O keytool é uma ferramenta utilitária que já vem com o JDK e fica localizada em <PATH_JAVA>\bin\keytool.exe. É essa ferramenta que será usada nas operações com o certificado.

# Para facilitar as chamadas, abra um terminal no diretório "<PATH_JAVA>\bin"
.\keytool.exe -list -keystore "<PATH_JAVA>\lib\security\cacerts" -storepass changeit

Esse comando deve retornar a lista dos certificados padrão existentes.

3. Importar o certificado

Com o arquivo do certificado da empresa em mãos, podemos usar o keytool para importá-lo no arquivo cacerts. Também é possível definir um alias para facilitar a identificação do certificado importado posteriormente.

.\keytool.exe -importcert -alias ca-interna-empresa -file "C:\certs\ca-raiz-empresa.crt" -keystore "<PATH_JAVA>\lib\security\cacerts" -storepass changeit -noprompt

Nota

A senha padrão do cacerts é changeit. Use um alias descritivo para facilitar a identificação futura. Se houver certificados intermediários, importe cada um com um alias diferente.

4. Verificar a importação

.\keytool.exe -list -keystore "<PATH_JAVA>\lib\security\cacerts" -storepass changeit -alias ca-interna-empresa

A saída deve exibir o alias, a data de criação e o tipo do certificado.

5. Reiniciar a aplicação Java

A JVM carrega o truststore na inicialização, então é necessário reiniciar o processo para que o novo certificado seja reconhecido.

Configurar para Python (requests / certifi)

A biblioteca requests não usa o truststore do sistema operacional nem o cacerts do Java. Ela depende do pacote certifi, que traz seu próprio bundle de CAs confiáveis (um arquivo cacert.pem).

1. Localizar o bundle do certifi

python -c "import certifi; print(certifi.where())"

Anote o caminho retornado (por exemplo, C:\Users\usuario\AppData\...\certifi\cacert.pem).

2. Criar o bundle customizado

Copie o bundle original e adicione o certificado da CA interna ao final:

# Cria o diretório de destino (se não existir)
New-Item -ItemType Directory -Path "C:\Users\<user>\Documents\Certs" -Force

# Copia o bundle original do certifi
Copy-Item -Path (python -c "import certifi; print(certifi.where())") -Destination "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem" -Force

# Adiciona o certificado raiz da CA interna ao final do bundle
Add-Content -Path "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem" -Value ""
Get-Content -Path "C:\certs\ca-raiz-empresa.crt" | Add-Content -Path "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem"

3. Configurar a variável de ambiente

Opção A: apenas para a sessão atual (teste rápido)

$env:REQUESTS_CA_BUNDLE = "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem"

Opção B: persistente para o usuário atual

[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem", "User")

Opção C: persistente para toda a máquina (requer PowerShell como Admin)

[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", "C:\Users\<user>\Documents\Certs\ca-bundle-empresa.pem", "Machine")

Dica

Se outros scripts ou bibliotecas além do requests também precisarem confiar na CA interna (por exemplo, httpx, urllib3), configure também a variável SSL_CERT_FILE com o mesmo caminho, seguindo o mesmo procedimento acima.

4. Verificar a configuração

Abra um novo terminal (para que a variável persistente seja carregada) e teste:

# Confirma que a variável está definida
echo $env:REQUESTS_CA_BUNDLE

# Testa a conexão
python -c "import requests; r = requests.get('https://developers.botcity.dev/api/v2/maestro/version'); print(r.status_code)"

5. Ambientes virtuais

A variável REQUESTS_CA_BUNDLE sobrescreve o comportamento padrão do requests, que seria consultar o certifi instalado no venv ativo. Com a variável definida, o requests ignora o certifi e usa diretamente o arquivo apontado. Por isso, funciona para qualquer venv sem necessidade de configuração adicional por ambiente.

Manutenção

Atualização do certifi

Quando o pacote certifi for atualizado via pip, o bundle customizado não é atualizado automaticamente (é uma cópia estática). Para recriar, basta repetir os passos 2 e 3 da seção anterior.

Remoção do certificado Java (se necessário)

keytool -delete -keystore "<JAVA_PATH>\lib\security\cacerts" -storepass changeit -alias ca-interna-empresa

Remoção das variáveis de ambiente Python (se necessário)

# Remove do escopo do usuário
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", $null, "User")

# Ou do escopo da máquina (requer Admin)
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", $null, "Machine")

Troubleshooting

Java: PKIX path building failed / unable to find valid certification path

  • Verifique se o JAVA_HOME aponta para a JVM correta que a aplicação utiliza.
  • Confirme que o certificado importado é o raiz (e não um intermediário).
  • Verifique se a aplicação não usa um truststore customizado via -Djavax.net.ssl.trustStore. Nesse caso, importe no truststore apontado, não no cacerts global.

Python: SSLCertVerifyError / CERTIFICATE_VERIFY_FAILED

  • Confirme que a variável REQUESTS_CA_BUNDLE está definida no terminal onde o script roda (echo $env:REQUESTS_CA_BUNDLE).
  • Verifique se o arquivo .pem contém tanto as CAs do certifi quanto o certificado da CA interna.
  • Se o erro persistir, teste com verify explícito para isolar o problema:
import requests
r = requests.get("https://seu-servidor.com", verify=r"C:\certs\ca-bundle-empresa.pem")
print(r.status_code)

Resumo

Etapa Java Python
Truststore cacerts (JKS) certifi (PEM)
Ferramenta keytool Cópia + concatenação de PEM
Comando de importação keytool -importcert ... Copy-Item + Add-Content
Variável de ambiente javax.net.ssl.trustStore (se truststore customizado) REQUESTS_CA_BUNDLE ou SSL_CERT_FILE
Reinício necessário Sim (JVM) Novo terminal

Nota

Substitua os caminhos de exemplo (como C:\certs\...) e o alias do certificado pelos valores reais do ambiente do cliente.