#!/intro
A segurança da informação é um pilar essencial em qualquer aplicação moderna, especialmente no contexto de armazenamento e gestão de ativos criptográficos.
No ecossistema Java, os keystores desempenham um papel fundamental nesta tarefa, servindo como repositórios seguros para chaves privadas, certificados e, em alguns casos, chaves simétricas. A sua utilização é essencial para garantir a autenticidade, confidencialidade e integridade das comunicações e operações criptográficas. A escolha do formato adequado de keystore pode ter implicações significativas tanto em termos de segurança como de interoperabilidade.
> stores
Apesar de frequentemente confundidos, keystores e truststores têm papéis distintos dentro do ecossistema de segurança em Java, especialmente no contexto de SSL/TLS, autenticação mútua e assinatura digital.
Um keystore armazena chaves privadas e os respetivos certificados – normalmente um par chave-certificado que identifica a aplicação ou servidor. Este ficheiro é usado sempre que a aplicação precisa de se autenticar perante outra entidade, por exemplo, ao estabelecer uma ligação TLS onde é exigido um certificado de cliente.
Por outro lado, um truststore armazena certificados de autoridades certificadoras e certificados públicos de entidades nas quais a aplicação confia. Não contém chaves privadas. A função da truststore é permitir que a aplicação valide a identidade de terceiros, verificando se o certificado apresentado por um servidor remoto ou cliente foi assinado por uma CA de confiança.
Embora possam tecnicamente ser ficheiros do mesmo tipo, a diferença está na função e no conteúdo. Uma aplicação Java pode usar o mesmo ficheiro como keystore e truststore, mas em ambientes de produção é prática comum mantê-los separados, com permissões distintas e uma gestão clara de identidade e confiança.
> JKS
O Java KeyStore (JKS) é o formato de keystore nativo da plataforma Java. Foi desenvolvido como uma solução simples para armazenar pares de chaves e certificados, cada entrada identificada por um alias.
Apesar da sua ampla utilização, especialmente em versões mais antigas do Java, o JKS apresenta limitações consideráveis em termos de segurança. Este formato, utilizado por omissão nas versões anteriores ao Java 9, utiliza algoritmos criptográficos proprietários para cifra das chaves privadas, atualmente considerados obsoletos. Baseia-se no SHA-1, que não é recomendado devido a colisões conhecidas, para a verificação de integridade, e utiliza um esquema de proteção por palavra-passe com algoritmos limitados, como o DES em modo ECB, considerado inseguro há décadas. A falta de autenticação forte e proteção contra modificações internas torna o JKS vulnerável a vários tipos de ataque, como modificação de entradas, substituição de certificados, e ataques de força bruta às passwords.
> JCEKS
O Java Cryptography Extension KeyStore (JCEKS) surge como uma extensão do JKS, com o objetivo de mitigar algumas das suas fragilidades. A segurança da proteção das chaves privadas é reforçada com a utilização do algoritmo Triple DES e introduz a capacidade de armazenar chaves simétricas, algo que o JKS não suporta.
No entanto, continua a apresentar debilidades, nomeadamente a utilização do algoritmo MD5 e uma função de derivação de chave (PBKDF) com tipicamente apenas algumas centenas de iterações, o que é muito inferior aos valores atualmente recomendados, expondo-o a ataques de força bruta com baixo custo computacional. O algoritmo Triple DES já não é considerado adequado para utilização futura, sendo recomendada a sua substituição por AES.
A integridade também não é autenticada com mecanismos modernos como HMAC, o que deixa o conteúdo vulnerável a modificações não detetadas. Por este motivo, o JCEKS não é adequado para aplicações que exijam um nível de proteção compatível com os padrões de segurança atualmente reconhecidos como aceitáveis.
> PKCS#12
O formato PKCS#12, também conhecido pelas extensões .p12 ou .pfx, é um padrão amplamente adotado para o armazenamento de chaves privadas, certificados e respetivas cadeias de certificação. Padronizado sob o protocolo PKCS da RSA, utiliza uma estrutura ASN.1 para codificar e encapsular os ativos criptográficos num ficheiro cifrado, suportando a proteção com palavra-passe tanto a nível global como por entrada individual.
Desde a versão 9 do Java, o PKCS#12 passou a ser o formato de keystore predefinido, substituindo o JKS. Esta transição deve-se ao facto de oferecer uma segurança superior e uma adoção mais alargada no setor tecnológico.
O formato suporta uma ampla variedade de algoritmos criptográficos, tanto para cifra como para verificação de integridade. É fundamental escolher algoritmos robustos e atualizados, como AES, PBKDF2 e SHA-256, evitando o uso de algoritmos obsoletos como RC2, DES ou SHA-1. Por fim, é essencial assegurar que os algoritmos escolhidos são compatíveis com a versão do JDK em que o keystore será utilizado, de forma a evitar erros de carregamento ou falhas de interoperabilidade.
> BKS
O formato BKS (Bouncy Castle KeyStore), criado no âmbito da biblioteca Bouncy Castle, surgiu como uma alternativa leve aos formatos nativos do Java, pensado sobretudo para ambientes com restrições de recursos como aplicações móveis ou sistemas embebidos.
Na sua implementação original, a derivação da chave de cifra é feita com SHA-1, e os dados são protegidos com Triple DES em modo CBC.
Estas escolhas expõem o formato a diversas fragilidades. O uso de SHA-1, atualmente considerado inseguro, combinado com a cifra sem mecanismos de autenticação, pode permitir alterações ao conteúdo sem deteção. A ausência de mecanismos de integridade autenticada, como HMAC, significa que alterações ao conteúdo podem passar despercebidas, mesmo quando a cifra é mantida, desde que a palavra-passe seja conhecida ou comprometida.
Devido a estas limitações, o BKS é hoje considerado criptograficamente fraco tornado-o inadequado face aos requisitos de segurança atuais.
> UBER
O formato UBER, também desenvolvido pela Bouncy Castle, representa uma evolução direta do BKS, oferecendo uma segurança consideravelmente superior. A sua principal característica técnica é a cifra do keystore na totalidade, incluindo os metadados. Tal impede a inspeção passiva de metadados, como o número de entradas, nomes de alias ou tipos de chaves, tornando o conteúdo opaco sem a palavra-passe correta.
A cifra é implementada através do algoritmo Twofish, um algoritmos simétrico em bloco de 128 bits, considerado uma alternativa segura ao AES. A derivação da chave baseia-se numa função PBE que aplica SHA-1 com múltiplas iterações, melhorando a proteção contra ataques de dicionário e força bruta. A confidencialidade dos dados é mantida de forma eficaz, ainda que o desempenho e compatibilidade com algumas ferramentas possa ser limitado.
> BCFKS
O formato BCFKS (Bouncy Castle FIPS Keystore) representa o ponto mais alto em termos de segurança dentro da família de keystores disponíveis para Java. Este formato foi concebido para estar em conformidade com o standard FIPS 140-2, exigido em sistemas regulados, como infraestruturas governamentais, militares ou de saúde.
A proteção da confidencialidade das chaves é assegurada por AES-256 em modo CCM, que combina cifra e autenticação num único algoritmo. A integridade do ficheiro é garantida por HMAC-SHA512, um algoritmo resistente a colisões e a ataques por extensão de mensagem. A derivação da chave de cifra é efetuada com PBKDF2 sobre HMAC-SHA512, com 1024 iterações (valor mínimo imposto pelo standard FIPS) e um sal criptograficamente aleatório de 512 bits, o que mitiga ataques por pré-computação e rainbow tables, proporcionando um grau de segurança extremamente elevado.
Este formato é ainda compatível com chaves assimétricas, simétricas e certificados, garantindo versatilidade num ambiente de alta segurança. Contudo, as exigências de conformidade impedem a utilização de mecanismos de cache em certas operações, o que pode penalizar a performance em sistemas de elevada rotação.
> conclusão
A evolução dos formatos de keystore no Java reflete a crescente exigência em termos de segurança. As soluções mais antigas, como JKS e JCEKS, embora ainda presentes em muitos sistemas, não oferecem garantias suficientes para aplicações modernas. Formatos como PKCS#12 e UBER introduzem melhorias substanciais em termos de cifra e autenticação, enquanto o BCFKS estabelece um novo padrão ao cumprir com os requisitos FIPS e utilizar algoritmos avançados e parametrizáveis.
A escolha da keystore representa uma decisão crítica na proteção de sistemas Java. A seleção do formato mais adequado deve resultar de uma análise de risco rigorosa, considerando o perfil de ameaça, o contexto operacional, os requisitos de interoperabilidade e as obrigações legais e regulamentares da organização. Negligenciar a escolha do formato de keystore compromete uma camada crítica da segurança em sistemas Java.
> status: sealed
> exit 0