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,.cerou.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
certifiinstalado (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:
Confirme que o arquivo existe:
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¶
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)
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_HOMEaponta 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 nocacertsglobal.
Python: SSLCertVerifyError / CERTIFICATE_VERIFY_FAILED
- Confirme que a variável
REQUESTS_CA_BUNDLEestá definida no terminal onde o script roda (echo $env:REQUESTS_CA_BUNDLE). - Verifique se o arquivo
.pemcontém tanto as CAs docertifiquanto o certificado da CA interna. - Se o erro persistir, teste com
verifyexplí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.