Utilizando Certificados mTLS do Azure Key Vault em Node.js

Cláudio Rapôso
9 min readMay 26, 2024

A segurança na comunicação entre serviços é um dos pilares fundamentais para qualquer aplicação moderna. Com o aumento das ameaças cibernéticas, garantir que os dados trocados entre serviços estejam protegidos se tornou crucial. Uma das técnicas mais robustas para alcançar essa segurança é o uso do mTLS (Mutual Transport Layer Security).

O mTLS (Mutual Transport Layer Security) é uma técnica eficaz para autenticar mutuamente clientes e servidores, garantindo a integridade e confidencialidade das comunicações. O Azure Key Vault simplifica o gerenciamento de certificados mTLS, fornecendo uma maneira segura e eficiente de armazenar, importar e gerenciar esses certificados.

O Que é mTLS?

O mTLS é uma extensão do protocolo TLS (Transport Layer Security), amplamente utilizado para proteger a comunicação entre clientes e servidores na internet. Enquanto o TLS tradicionalmente garante que o servidor seja autenticado pelo cliente, o mTLS vai um passo além, autenticando ambos os lados da comunicação. Isso significa que tanto o cliente quanto o servidor precisam apresentar e verificar certificados digitais.

Como Funciona o mTLS?

O processo de autenticação mútua no mTLS envolve várias etapas:

  1. Handshake Inicial: Quando um cliente tenta se conectar a um servidor, ambos iniciam o processo de handshake TLS.
  2. Certificado do Servidor: O servidor envia seu certificado digital ao cliente, provando sua identidade.
  3. Certificado do Cliente: Em vez de apenas o servidor ser autenticado, o cliente também envia seu certificado digital ao servidor.
  4. Verificação de Certificados: Ambos os lados verificam os certificados recebidos contra uma Autoridade Certificadora (CA) confiável.
  5. Estabelecimento de Sessão: Após a verificação, uma chave de sessão é gerada para criptografar os dados trocados durante a sessão.

Benefícios do mTLS

  1. Autenticação Forte: mTLS garante que ambos os lados da comunicação sejam autenticados, reduzindo o risco de ataques de spoofing.
  2. Criptografia de Dados: Todos os dados trocados são criptografados, protegendo contra interceptações.
  3. Integridade dos Dados: Assegura que os dados não foram alterados durante a transmissão.
  4. Prevenção de Ataques Man-in-the-Middle (MitM): Autenticando ambos os lados, torna-se extremamente difícil para um atacante se inserir na comunicação.

Implementando mTLS em Suas Aplicações

Implementar mTLS pode parecer uma tarefa complexa, mas com as ferramentas e práticas certas, o processo se torna mais gerenciável. Aqui estão alguns passos para começar:

  1. Gerenciamento de Certificados: Utilize uma infraestrutura de chave pública (PKI) para gerenciar e distribuir certificados digitais.
  2. Configuração do Servidor: Configure seu servidor para solicitar e verificar certificados de clientes. Servidores como Nginx, Apache e servidores de aplicação como Kubernetes suportam mTLS.
  3. Configuração do Cliente: Configure seus clientes para apresentar certificados ao servidor. Ferramentas como OpenSSL podem ser utilizadas para gerar e gerenciar esses certificados.
  4. Rotação de Certificados: Estabeleça um processo regular para a rotação de certificados, minimizando o risco de comprometimento.

Casos de Uso Comuns

  1. Microserviços: Em arquiteturas de microserviços, mTLS pode garantir a segurança das comunicações internas entre os serviços.
  2. APIs Sensíveis: Para APIs que lidam com dados sensíveis, mTLS oferece uma camada extra de proteção.
  3. Conexões de Banco de Dados: Autenticar tanto o banco de dados quanto o cliente, garantindo que apenas clientes autorizados possam acessar o banco.

Desafios e Considerações

Embora o mTLS ofereça uma segurança robusta, há alguns desafios a serem considerados:

  1. Gerenciamento de Certificados: Manter certificados atualizados e gerenciar sua distribuição pode ser complexo.
  2. Compatibilidade: Nem todos os clientes ou servidores suportam mTLS de forma nativa.
  3. Desempenho: O processo adicional de autenticação pode introduzir uma pequena latência na comunicação.

Principais Funcionalidades do Azure Key Vault

  1. Gerenciamento de Segredos: Armazene e acesse senhas, tokens de acesso e outros segredos com segurança.
  2. Gerenciamento de Chaves: Crie e controle chaves de criptografia usadas para proteger dados.
  3. Gerenciamento de Certificados: Simplifique o processo de aquisição e renovação de certificados SSL/TLS.
  4. Auditoria e Monitoramento: Rastreie o uso e o acesso aos segredos com logs detalhados.
  5. Controle de Acesso Granular: Utilize políticas de controle de acesso baseadas em funções (RBAC) para gerenciar permissões.

Como Funciona o Azure Key Vault?

O Azure Key Vault funciona como um cofre digital onde você pode armazenar e gerenciar segredos, chaves e certificados. Aqui estão os principais componentes e o fluxo de trabalho:

  1. Criação do Cofre: Crie um cofre no Azure para armazenar seus itens secretos.
  2. Armazenamento de Segredos: Adicione segredos, chaves e certificados ao cofre.
  3. Configuração de Acesso: Defina políticas de acesso para controlar quem pode acessar ou gerenciar os itens no cofre.
  4. Integração com Aplicações: Utilize APIs e SDKs do Azure para que suas aplicações possam acessar os segredos de maneira segura.

Benefícios do Azure Key Vault

  1. Segurança Reforçada: Os segredos são armazenados em módulos de segurança de hardware (HSMs) certificados, garantindo a proteção contra acessos não autorizados.
  2. Escalabilidade: Integrado ao Azure, o Key Vault oferece alta disponibilidade e pode escalar conforme suas necessidades crescem.
  3. Simplificação da Gestão de Segredos: Centraliza a gestão de segredos, chaves e certificados, facilitando o controle e a administração.
  4. Conformidade: Ajuda a atender requisitos de conformidade, mantendo registros de auditoria detalhados.
  5. Automatização: Automatiza a renovação de certificados e a rotação de chaves, reduzindo a carga administrativa.

Casos de Uso Comuns

  1. Armazenamento de Credenciais de Banco de Dados: Armazene credenciais de acesso ao banco de dados no Key Vault e recupere-as em tempo de execução.
  2. Gerenciamento de Certificados SSL/TLS: Simplifique a aquisição e renovação de certificados para suas aplicações web.
  3. Proteção de Chaves de Criptografia: Armazene e gerencie chaves usadas para criptografar dados sensíveis.

Importação e Gerenciamento de Certificados mTLS com Azure Key Vault Usando Node.js

Vamos explorar como usar o Azure Key Vault para importar e gerenciar certificados mTLS com uma aplicação Node.js.

Configuração Inicial

Antes de começar, você precisa:

  1. Configurar um Azure Key Vault: Crie um Key Vault no portal do Azure.
  2. Configurar uma Identidade Gerenciada (Managed Identity): Se sua aplicação estiver rodando em um serviço do Azure (como Azure VM, App Service ou AKS), configure uma Identidade Gerenciada para acessar o Key Vault.

Instalando Dependências

Primeiro, instale as bibliotecas necessárias:

npm install axios @azure/identity @azure/keyvault-certificates @azure/keyvault-secrets

Código de Exemplo de importação

A seguir está um exemplo de código em Node.js que busca um certificado mTLS do Azure Key Vault e o importa:

const { CertificateClient } = require('@azure/keyvault-certificates');
const { DefaultAzureCredential } = require('@azure/identity');

/**
* Função principal para importar um certificado para o Azure Key Vault.
*/
async function main() {
// Obtém as credenciais padrão do Azure.
const credential = new DefaultAzureCredential();

// Nome do seu cofre do Azure Key Vault.
const keyVaultName = 'seu-nome-do-key-vault';

// URL do seu cofre do Azure Key Vault.
const url = `https://${keyVaultName}.vault.azure.net`;

// Cria um cliente para gerenciar certificados no Azure Key Vault.
const client = new CertificateClient(url, credential);

// Nome do segredo onde o certificado será importado.
const secretName = 'nome-do-seu-certificado';

// Certificado a ser importado (formato PEM).
const certificate = `-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANr3uZqBZ0KtMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDAoyMDAwMDAwMDAxMREwDwYDVQQHDAhNZWxib3VybmUx
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDd7+gqlso5VHYB
...
-----END PRIVATE KEY-----`;

// Codifica o certificado em base64.
const base64EncodedCertificate = Buffer.from(certificate).toString('base64');

// Define a política para importação do certificado.
const policy = {
issuerName: 'Unknown',
contentType: 'application/x-pem-file',
keyProperties: {
exportable: true,
keyType: 'RSA',
keySize: 2048,
reuseKey: false,
},
};

try {
// Importa o certificado para o Azure Key Vault.
const certificateBundle = await client.importCertificate(secretName, base64EncodedCertificate, {
policy: policy,
enabled: true,
});

console.log('Certificate imported:', certificateBundle);
} catch (error) {
console.error('An error occurred:', error);
}
}

// Executa a função principal.
main().catch((error) => {
console.error('An error occurred in the main function:', error);
process.exit(1);
});

Detalhes Importantes

  1. Configuração do Cliente e Credenciais:DefaultAzureCredential é usado para obter credenciais automaticamente de diferentes fontes, como variáveis de ambiente, Identidade Gerenciada do Azure, etc. CertificateClient é o cliente para operações de certificado no Azure Key Vault.
  2. Definição dos Detalhes do Cofre: keyVaultName e url são configurados com base no nome do seu cofre Key Vault.
  3. Certificado em Formato PEM: Substitua o conteúdo entre -----BEGIN CERTIFICATE----- e -----END CERTIFICATE----- e entre -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY----- pelo seu próprio certificado e chave privada.
  4. Codificação Base64: O certificado é codificado em base64 para ser compatível com o Azure Key Vault.
  5. Política de Certificado: Definimos a política do certificado, especificando propriedades como tipo de chave (RSA), tamanho da chave (2048), se a chave é exportável, etc.
  6. Importação do Certificado: Utilizamos importCertificate para importar o certificado codificado em base64 para o Key Vault.
  7. Tratamento de Erros: Erros são capturados e logados para depuração.

Código de Exemplo para Visualizar Certificado e Chave Privada

A seguir está um exemplo de código em Node.js que busca um certificado mTLS no Azure Key Vault e o restaura para uma requisição:

const { DefaultAzureCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
const https = require("https");
const axios = require("axios");

/**
* Função principal para visualizar um certificado do Azure Key Vault e fazer uma requisição HTTPS.
*/
async function main() {
// Obtém as credenciais padrão do Azure.
const credential = new DefaultAzureCredential();

// Nome do seu cofre do Azure Key Vault.
const keyVaultName = 'seu-nome-do-key-vault';

// URL do seu cofre do Azure Key Vault.
const url = `https://${keyVaultName}.vault.azure.net`;

// Cria um cliente para gerenciar segredos no Azure Key Vault.
const certificateName = new SecretClient(url, credential);

// Nome do segredo onde o certificado está armazenado.
const secretName = 'nome-do-seu-certificado';

// Obtém o segredo do Azure Key Vault que contém o certificado.
const secret = await secretClient.getSecret(certificateName);

// Extrai a chave privada e o certificado do valor do segredo.
const privateKey = secret.value.match(/-----BEGIN PRIVATE KEY-----[\s\S]+?-----END PRIVATE KEY-----/)[0];
const certificate = secret.value.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/)[0];

console.log("Private Key:", privateKey);
console.log("Certificate:", certificate);

// Configura o agente HTTPS com o certificado e a chave privada.
const httpsAgent = new https.Agent({
rejectUnauthorized: false, // Certificado autoassinado
cert: certificate,
key: privateKey,
});

// Cria uma instância do Axios com o agente HTTPS configurado.
const axiosInstance = axios.create({
baseURL: "https://sua-api.com", // Certifique-se de usar HTTPS para uma conexão segura
httpsAgent,
});

// Faz uma requisição GET à API.
const response = await axiosInstance.get("/register");

console.log("Response:", response.data);
}

// Executa a função principal.
main().catch((error) => {
console.error("An error occurred:", error);
process.exit(1);
});

Detalhes Importantes

  1. Visualização do Certificado: Utilizamos expressões regulares para extrair a chave privada e o certificado do valor do segredo obtido do Azure Key Vault.
  2. Configuração do Agente HTTPS: Usamos a classe https.Agent do Node.js para configurar um agente HTTPS com o certificado e a chave privada.
  3. Criação da Instância do Axios: Configuramos uma instância do Axios com o agente HTTPS que acabamos de criar para garantir que a requisição HTTPS seja feita corretamente.
  4. Requisição à API com Axios: Utilizamos a instância do Axios para fazer uma requisição GET à API.

Certifique-se de substituir "https://sua-api.com" pelo URL correto da sua API. Este código assume que a API está disponível via HTTPS e que aceita certificados autoassinados. O uso de rejectUnauthorized: false pode ser adequado para ambientes de desenvolvimento, mas lembre-se de remover isso em ambientes de produção para garantir a segurança da comunicação.

Conclusão

Implementar mTLS pode parecer desafiador inicialmente, mas com a abordagem certa, seus benefícios em garantir a segurança das comunicações entre serviços são inegáveis. Este exemplo demonstrou como importar certificados para o Azure Key Vault usando Node.js, assegurando um armazenamento e gerenciamento seguros, além de aproveitar funcionalidades avançadas, como proteção por HSMs e automação da rotação de certificados.

Ao optar pelo Azure Key Vault para gerenciar certificados mTLS, você garante a segurança reforçada dos certificados, armazenados em um ambiente protegido por HSMs. Além disso, a centralização do gerenciamento simplifica operações de TI, enquanto a automação de tarefas críticas reduz o risco de falhas de segurança. Isso não só fortalece a conformidade com políticas e regulamentações, mas também proporciona uma abordagem estratégica e eficaz para garantir a segurança dos dados em um ambiente onde a proteção das informações é fundamental.

--

--

Cláudio Rapôso

Microsoft MVP | Software Architect | Teacher | React | React Native | Node | Autor do Livro NestJS: Do Zero até a primeira API | MCT | 12x Msft | 2x AWS