O acesso à informação em saúde é possível apenas em cenários restritos e bem definidos. Para requisitar qualquer informação à RNDS, por exemplo, primeiro é preciso obter um token de acesso. A obtenção ocorre por meio de serviço específico.
A requisição para este serviço é GET /api/token. O token só será recuperado por esta requisição se o certificado digital empregando por quem efetua esta requisição já estiver devidamente configurado com o serviço. Esta requisição usa Two Way SSL como mecanismo de autenticação. Se o resultado é positivo, então retornará um JWT. Caso contrário, a requisição falha.
- Client side SSL
- Spring security with basic auth
- certificate folder
- Server side ssl replacing basic auth
- new files in certificate folder
- Full implementation of /certificate endpoint
- Ssl context reload
- Mock for certificate alias search (later should be replaced for database)
- Replacement of enpoints '/autorizado' for '/verify'
- Dinamic memory-only/filed truststore
- Asymmetric JWT secrect for generation and validation
Nesse projeto é utilizado autenticação por certificado X.509. Ou seja enquanto uma conexão segura é estabelecida, o cliente verifica o servidor de acordo com seu certificado (emitido por uma autoridade de certificação confiável).
Mas além disso, no Spring Security, o X.509 pode ser usado para verificar a identidade de um cliente pelo servidor durante a conexão. Isso é chamado de "autenticação mútua".
A geração de certificado e importação começa ao considerar uma autoriade de certificação confiável(CA).
Para poder assinar os certificados do lado do servidor e do lado do cliente, precisamos primeiro criar nosso próprio certificado raiz de autoridade de certificação autoassinado. Dessa forma, agiremos como nossa própria autoridade de certificação. A criação ocorre através do seguinte comando:
openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout rootCA.key -out rootCA.crt
-
openssl: Esta é a ferramenta de linha de comando do OpenSSL.
-
req: Este subcomando é usado para solicitações de certificados X.509 e funções relacionadas.
-
x509: Esta opção especifica que um certificado autoassinado está sendo criado.
-
sha256: Esta opção especifica o algoritmo de hash a ser usado, neste caso, SHA-256.
-
days 3650: Isso define o período de validade do certificado para 3650 dias (aproximadamente 10 anos).
-
newkey rsa:4096: Isso gera uma nova chave privada RSA com um comprimento de chave de 4096 bits.
-
keyout rootCA.key: Isso especifica o arquivo onde a chave privada gerada será salva.
-
out rootCA.crt: Isso especifica o arquivo onde o certificado X.509 gerado será salvo.
Em resumo, este comando gera um certificado raiz autoassinado com uma chave privada RSA de 4096 bits, usando o algoritmo de hash SHA-256, e define sua validade para 10 anos. A chave privada é salva em um arquivo chamado rootCA.key, e o certificado X.509 é salvo em um arquivo chamado rootCA.crt.
Criação de um "keystore". Definição: (armazenamento de chaves) é um repositório seguro utilizado para armazenar chaves criptográficas, certificados digitais e, em alguns casos, segredos criptograficamente sensíveis. No nosso caso é um repositório de chave privada, a chave privada do nosso servidor.
openssl req -new -newkey rsa:4096 -keyout localhost.key -out localhost.csr
O comando acima utiliza o OpenSSL para criar uma solicitação de assinatura de certificado (CSR) e uma nova chave privada RSA. Vamos analisar o comando passo a passo:
-
openssl: A ferramenta de linha de comando OpenSSL.
-
req: Subcomando usado para gerar e processar solicitações de certificado X.509.
-
new: Indica que uma nova CSR será gerada.
-
newkey rsa:4096: Gera uma nova chave privada RSA com um comprimento de 4096 bits.
-
keyout localhost.key: Especifica o arquivo onde a nova chave privada será salva. Neste caso, ela é salva como "localhost.key".
-
out localhost.csr: Especifica o arquivo onde a CSR será salva. Neste caso, ela é salva como "localhost.csr".
É necessário um arquivo (localhost.ext) de configuração externo com o seguinte conteúdo:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
Assine o request com o nosso CA:
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in localhost.csr -out localhost.crt -days 365 -CAcreateserial -extfile localhost.ext
Este comando OpenSSL está sendo utilizado para assinar uma solicitação de certificado (CSR) com a chave privada de uma Autoridade Certificadora (CA), gerando assim um certificado X.509 para um servidor. Aqui está uma explicação dos parâmetros utilizados:
-
openssl: A ferramenta de linha de comando OpenSSL.
-
x509: Subcomando utilizado para manipular certificados X.509.
-
req: Indica que a entrada é uma CSR (solicitação de certificado).
-
CA rootCA.crt: Especifica o certificado da Autoridade Certificadora (CA) que será usado para assinar a CSR.
-
CAkey rootCA.key: Especifica a chave privada da CA que será usada para assinar a CSR.
-
in localhost.csr: Especifica o arquivo contendo a CSR que será assinada.
-
out localhost.crt: Especifica o arquivo de saída onde o certificado assinado será salvo.
-
days 365: Define a validade do certificado para 365 dias.
-
CAcreateserial: Cria um arquivo serial para acompanhar os números de série dos certificados assinados pela CA.
-
extfile localhost.ext: Especifica um arquivo de configuração contendo extensões adicionais para serem incluídas no certificado. Essas extensões podem incluir informações como alternativas de nome do domínio (SANs) e outras configurações específicas.
Primeiramente temos que empacotar nossa chave primária com o certificado, usamos o comando abaixo:
openssl pkcs12 -export -out localhost.p12 -name "localhost" -inkey localhost.key -in localhost.crt
-
openssl: A ferramenta de linha de comando OpenSSL.
-
pkcs12: Subcomando usado para manipular arquivos no formato PKCS#12.
-
export: Indica que você deseja criar um arquivo PKCS#12.
-
out localhost.p12: Especifica o nome do arquivo de saída, que será um arquivo PKCS#12. Neste caso, é "localhost.p12".
-
name "localhost": Especifica o nome do "objeto amigável" (friendly name) que será associado ao certificado dentro do arquivo PKCS#12.
-
inkey localhost.key: Especifica o arquivo contendo a chave privada associada ao certificado.
-
in localhost.crt: Especifica o arquivo contendo o certificado.
Agora criamos nosso keystore, junto com o nosso .p12
keytool -importkeystore -srckeystore localhost.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS
-
keytool: Uma ferramenta de linha de comando que faz parte do kit de ferramentas do Java (Java Development Kit - JDK), utilizada para gerenciar certificados, chaves e keystores.
-
importkeystore: Este subcomando especifica que você deseja importar um keystore.
-
srckeystore localhost.p12: Especifica o keystore de origem, que neste caso é o arquivo "localhost.p12".
-
srcstoretype PKCS12: Indica o tipo de keystore de origem, que é PKCS#12. Isso é necessário porque o formato do keystore de origem é diferente do formato padrão do Java KeyStore (JKS).
-
destkeystore keystore.jks: Especifica o keystore de destino, que será criado com o nome "keystore.jks". Este é um keystore no formato Java KeyStore (JKS).
-
deststoretype JKS: Indica o tipo de keystore de destino, que é JKS.
De maneira simplificada é um Keystore de Chave Pública.Possui a finalidade de Armazenar certificados de entidades confiáveis.
keytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file rootCA.crt -keystore truststore.jks
-
keytool: A ferramenta de linha de comando do Java para gerenciar certificados, chaves e keystores.
-
import: Especifica que você deseja importar um certificado.
-
trustcacerts: Indica que o certificado a ser importado deve ser tratado como uma CA, ou seja, um certificado de autoridade de certificação.
-
noprompt: Esta opção indica que o comando não deve solicitar confirmação do usuário antes de executar a operação.
-
alias ca: Define um alias (apelido) para o certificado que está sendo importado. Neste caso, o alias é definido como "ca".
-
ext san=dns:localhost,ip:127.0.0.1: Esta opção é utilizada para adicionar extensões ao certificado importado. No caso, são especificadas alternativas de nome do assunto (Subject Alternative Name - SAN) contendo o DNS "localhost" e o endereço IP "127.0.0.1".
-
file rootCA.crt: Especifica o arquivo que contém o certificado a ser importado, que neste caso é "rootCA.crt".
-
keystore truststore.jks: Especifica o truststore de destino, onde o certificado será importado. Neste caso, o truststore é salvo como "truststore.jks".
Cria-se o certificado com o comando já utilizado anteriormente
openssl req -new -newkey rsa:4096 -nodes -keyout teste.key -out teste.csr
Assina-se o certificado com nosso root CA através do também já apresentado comando:
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in clientBob.csr -out clientBob.crt -days 365 -CAcreateserial
Com os certificados devidamente assinados pelo rootCa, os arquivos keystore e truststore estarão devidamente populados e podem ser usador na aplicação se enviados através das variáveis TRUST_STORE_PATH/TRUST_STORE_PASSWORD e KEY_STORE_PATH/KEY_STORE_PASSWORD. Caso prefira, o protótipo já possui arquivos padrões.