Eu tenho um aplicativo que usa criptografia AES de 256 bits, que não é suportada pelo Java imediatamente. Sei que para que isso funcione corretamente, instalo os frascos de força ilimitados do JCE na pasta de segurança. Isso é bom para mim, como desenvolvedor, posso instalá-los.
Minha pergunta é que, como esse aplicativo será distribuído, os usuários finais provavelmente não terão esses arquivos de política instalados. Fazer o download do usuário final apenas para que o aplicativo funcione não é uma solução atraente.
Existe uma maneira de executar meu aplicativo sem substituir arquivos na máquina do usuário final? Um software de terceiros que pode lidar com isso sem os arquivos de política instalados? Ou uma maneira de apenas referenciar esses arquivos de políticas de dentro de um JAR?
fonte
Respostas:
Existem algumas soluções comumente citadas para esse problema. Infelizmente, nenhum deles é totalmente satisfatório:
Mas depois há reflexão. Existe algo que você não possa fazer usando reflexão?
Simplesmente chame
removeCryptographyRestrictions()
de um inicializador estático ou algo semelhante antes de executar qualquer operação criptográfica.A
JceSecurity.isRestricted = false
parte é tudo o que é necessário para usar cifras de 256 bits diretamente; no entanto, sem as duas outras operações,Cipher.getMaxAllowedKeyLength()
o relatório continuará sendo reportado por 128, e os conjuntos de criptografia TLS de 256 bits não funcionarão.Esse código funciona no Oracle Java 7 e 8 e ignora automaticamente o processo no Java 9 e no OpenJDK onde não é necessário. Sendo um truque feio, afinal, provavelmente não funciona nas VMs de outros fornecedores.
Também não funciona no Oracle Java 6, porque as classes JCE privadas são ofuscadas por lá. A ofuscação não muda de versão para versão, portanto, ainda é tecnicamente possível oferecer suporte ao Java 6.
fonte
final
campo em 8u111, modifiquei-o para que ele possa alterar o campo final, seguindo esta resposta . O resultado é quase o mesmo que a nova versão do ntoskrnl, exceto que eu não declareimodifiersField
comofinal
. Um dos meus usuários relata que ele também funciona no 8u112.Agora, isso não é mais necessário para o Java 9 , nem para qualquer versão recente do Java 6, 7 ou 8. Finalmente! :)
De acordo com JDK-8170157 , a política criptográfica ilimitada agora está ativada por padrão.
Versões específicas do problema do JIRA:
Observe que, por algum motivo estranho, o comportamento antigo é necessário no Java 9, ele pode ser configurado usando:
fonte
Aqui está a solução: http://middlesphere-1.blogspot.ru/2014/06/this-code-allows-to-break-limit-if.html
fonte
java.security.InvalidKeyException: Wrong algorithm: AES or Rijndael required
isRestricted
campo se tornou final ( bugs.openjdk.java.net/browse/JDK-8149417 ). A resposta do @ ntoskrnl cuida de qualquer possível inclusão de um modificador "final". O comentário de @M.Dudley sobre o Contrato de Licença Java também se aplica.O Bouncy Castle ainda requer jarros instalados até onde eu sei.
Fiz um pequeno teste e pareceu confirmar isso:
http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions
fonte
A partir do JDK 8u102, as soluções postadas baseadas na reflexão não funcionarão mais: o campo que essas soluções configuradas estão agora
final
( https://bugs.openjdk.java.net/browse/JDK-8149417 ).Parece que voltou a (a) usar o Bouncy Castle ou (b) instalar os arquivos de políticas do JCE.
fonte
isRestricted
campo, porque cuida de uma possível adição de um modificador "final".Para uma biblioteca de criptografia alternativa, dê uma olhada no Bouncy Castle . Possui AES e muitas funcionalidades adicionais. É uma biblioteca liberal de código aberto. Você precisará usar a API leve e proprietária do Bouncy Castle para que isso funcione.
fonte
Você poderia usar o método
para testar o comprimento da chave disponível, use isso e informe o usuário sobre o que está acontecendo. Algo que indica que seu aplicativo está retornando às chaves de 128 bits devido aos arquivos de política não estarem instalados, por exemplo. Usuários preocupados com segurança instalarão os arquivos de políticas, outros continuarão usando chaves mais fracas.
fonte
Para nosso aplicativo, tínhamos uma arquitetura de servidor cliente e permitíamos apenas descriptografar / criptografar dados no nível do servidor. Portanto, os arquivos JCE são necessários apenas lá.
Tivemos outro problema em que precisávamos atualizar um jar de segurança nas máquinas clientes, por meio do JNLP, ele substitui as bibliotecas
${java.home}/lib/security/
e a JVM na primeira execução.Isso fez funcionar.
fonte
Aqui está uma versão atualizada da resposta ntoskrnl . Além disso, contém uma função para remover o modificador final como o Arjan mencionado nos comentários.
Esta versão funciona com o JRE 8u111 ou mais recente.
fonte
((Map<?, ?>) perms.get(defaultPolicy)).clear();
gera um erro do compilador. Comentar não parece afetar sua funcionalidade. Essa linha é necessária?Aqui está uma versão modificada do código do @ ntoskrnl, apresentando
isRestrictedCryptography
check por log slf4j realCipher.getMaxAllowedKeyLength
e suporte à inicialização de singleton a partir do bootstrap do aplicativo como este:Esse código para de corrigir corretamente quando a política ilimitada se torna disponível por padrão no Java 8u162, como a resposta do @ cranphin prevê.
fonte
Durante a instalação do seu programa, basta solicitar ao usuário e fazer o download de um script de lote do DOS ou de shell do Bash e copiar o JCE no local apropriado do sistema.
Eu costumava fazer isso para um serviço da web do servidor e, em vez de um instalador formal, fornecia apenas scripts para configurar o aplicativo antes que o usuário pudesse executá-lo. Você pode tornar o aplicativo impossível de executar até que eles executem o script de instalação. Você também pode fazer com que o aplicativo reclame que o JCE está ausente e peça para baixar e reiniciar o aplicativo?
fonte