Criptografia Assimétrica usando JSE 1.5

Olá,

Venho tentando a várias semanas criptografar dados usar criptografia assimétrica sem sucesso. A única tentativa que funcionou foi quando utilizei o método “doFinal()” do Cipher com uma instância do tipo “RSA” utilizando apenas meia dúzia de caracteres como sendo o conteúdo a ser criptografado.

Contudo, isso não reflete um cenário real. Já tentei todas as alternativas que encontrei por ai, inventei mais umas, mas mesmo assim não funcionou.

O que eu quero é criptografar uma frase grande (para testes iniciais, depois vou tentar coisas mais complexas).

se usar cipher.doFinal(“frase longa…”.getBytes()); recebo exception dizendo que não posso usar byte arrays maior que 245.
“javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes”

se tento usar o método cipher.update(byte[]) de 245 em 245 bytes, executando um doFinal() depois da última “remessa” de bytes, acontece a mesma exception.

tentei usar o CipherInputStream usando como input a frase transformada para bytes (e colocada dentro de um ByteArrayInputStream). Quando eu tento ler informações do CipherInputStream, esse sempre me retorna 0 (como se não tivessem dados lah). Porém, existem dados no ByteArrayInputStream (pois consigo ler dados dele).
Estou inicializando o cipher com:

Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

a publicKey eu pego da seguinte maneira:

KeyStore pkcs12KeyStore = KeyStore.getInstance("PKCS12"); pkcs12KeyStore.load(new FileInputStream("D:\\temp\\certificados\\chaves privadas\\private.p12"), "teste".toCharArray()); Certificate publicCertificate = pkcs12KeyStore.getCertificate("1"); publicKey = publicCertificate.getPublicKey()

Eu não sei porque não consigo criptografar uma mensagem (coisa que deveria ser simples). Se alguém quiser detalhes de como gerei aquela chave, me pergunte. Mas como o algoritmo não reclamou delas, parece que estão válidas.

Eu estou começando a desconfiar que tem algum bug na API… mas somente alguém que já tenha conseguido fazer alguma coisa mais elaborada poderá me dizer.

Se alguém tiver qualquer pista, informação ou ajuda para me passar, eu agradeceria (pode ser até outra forma de usar criptografia assimétrica).

Obrigado pela atenção.
Giovani

Olá

Já experimentou usar RSA com outro provider como o Bouncy Castle ou o Criptix JCE?

No caso de usar o Bouncy Castle, no arquivo java.security você precisa acrescentar a linha:
security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider
onde N é a ordem de preferência.

Acho que o código ficaria assim.

Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");

As outras mudanças dependem do trecho de código que não mostrou. Aliás, seria bom mostrar tudo.

[]s
Luca

RSA não é feito para criptografar coisas “grandes”. Por exemplo, para uma chave de 1024 bits (= 128 bytes), não se deve criptografar nada maior que 128 bytes, que é o tamanho da chave.
Não é bug na API; talvez seja um bug na documentação (que não indica que não se deve criptografar coisas grandes com RSA.)
Se não me engano, criptografar coisas “grandes” com o RSA expõe uma vulnerabilidade no algoritmo RSA também, mas não consigo me lembrar de onde li isso.
Normalmente o que se faz é o seguinte:

  • Gerar uma chave para um algoritmo simétrico (como o AES - 256 bits, ou ou Triple-DES - 168 bits)
  • Criptografar os dados com o algoritmo simétrico
  • Criptografar essa chave com RSA
    O outro lado deve fazer o seguinte:
  • Decifrar a chave com RSA
  • Decifrar os dados que foram criptografados com o algoritmo simétrico, usando a chave decifrada.
    É muito mais rápido, mais seguro, e pode criptografar coisas de qualquer tamanho. Esse esquema é usado no PKCS#7 (envelopedData) e no PGP.

t