Cifragem/decifragem de objecto com RSA 1024 bits

5 respostas
merlinX

Pessoal estou a ter problemas a cifrar/decifrar um objecto com encriptação RSA 1024 bits:

tenho:

public SealedObject cifrarObjecto(Serializable ob, PublicKey pubKey) {
        
            SealedObject objectoCifrado = null;
            try {

                Cipher ecifrador = Cipher.getInstance("RSA");
                ecifrador.init(Cipher.ENCRYPT_MODE, pubKey);

                // cifrar o objecto
                objectoCifrado =  new SealedObject(ob, ecifrador);
                
            } catch (IOException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalBlockSizeException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvalidKeyException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchPaddingException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            }
        
            return objectoCifrado;
     
        }

tenho:

public Object decifrarObjecto(SealedObject obCifrado, PrivateKey priKey) {
            Object objectoDecifrado = null;
            try {

                // inicia decifrador
                Cipher dcipher = Cipher.getInstance("RSA");
                dcipher.init(Cipher.DECRYPT_MODE, priKey);

                // Unseal (decrypt) the class
                objectoDecifrado = (Object) obCifrado.getObject(dcipher);

            } catch (IOException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalBlockSizeException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BadPaddingException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvalidKeyException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchPaddingException ex) {
                Logger.getLogger(ElectionSecurity.class.getName()).log(Level.SEVERE, null, ex);
            }
            return objectoDecifrado;
        }

para testar fiz num main(…)

PublicKey pub = es.extrairChavePublica(new File("chaveiroPublico.jks"), "key", "password");
            SealedObject tuploCifrado = es.cifrarObjecto(ot, pub);
            System.out.println("O tuplo foi cifrado!");
            PrivateKey pri = es.extrairChavePrivada(new File("chaveiroPrivado.jks"), "key", "password");
            Tuplo<Object> tuploDecifrado = ( Tuplo<Object> ) es.decifrarObjecto(tuploCifrado, pri);
            System.out.println("O tuplo foi decifrado!");
            System.out.printf("Object tuple: %s\n", tuploDecifrado.toString());

Então dá-me este erro que não estou a ver muito bem como contornar…

11/Mai/2009 19:45:27 ElectionSecurity cifrarObjecto

SEVERE: null

javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes

at com.sun.crypto.provider.RSACipher.a(DashoA13*)

at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*)

at javax.crypto.Cipher.doFinal(DashoA13*)

at javax.crypto.SealedObject.(DashoA13*)

at ElectionSecurity.cifrarObjecto(ElectionSecurity.java:536)

O tuplo foi decifrado!

at testSecurity.main(testSecurity.java:56)

11/Mai/2009 19:45:27 ElectionSecurity decifrarObjecto

SEVERE: null

java.security.InvalidKeyException: No installed provider supports this key: (null)

at javax.crypto.Cipher.a(DashoA13*)

at javax.crypto.Cipher.init(DashoA13*)

at javax.crypto.Cipher.init(DashoA13*)

at ElectionSecurity.decifrarObjecto(ElectionSecurity.java:566)

at testSecurity.main(testSecurity.java:59)

11/Mai/2009 19:45:27 testSecurity main

SEVERE: null

java.lang.NullPointerException

at testSecurity.main(testSecurity.java:61)

Qualquer ajuda é bem vinda, obrigado desde já…

5 Respostas

T

Esse erro não pode ser contornado.
De modo geral, RSA não pode codificar em um bloco uma quantidade de dados maior que o tamanho da chave, menos alguns bytes.

O que se faz, normalmente, é gerar uma chave secreta para um algoritmo simétrico (como AES ou TripleDES), criptografar os dados usando esse algoritmo simétrico, e a seguir criptografar a chave secreta com o RSA.

Para decifrar os dados, você decifra os dados criptografados com RSA (retornando a chave secreta), e a seguir decifra os dados que foram criptografados com o algoritmo secreto (AES, TripleDES).

merlinX

Olá, antes de mais obrigado.

Mas será que não existe mesmo hipótese de cifrar/decifrar directamente com RSA, por exemplo cifrando bloco a bloco, ex: imaginando que os dados a cifrar têm 200 bytes cifrar 100 a primeira vez e 100 a segunda?
Parece-me complicado, mas será que não dá?
É que a idéia era mesmo cifrar/decifrar os dados directamente com RSA 1024 bits.

T

Dar dá, mas isso não é criptograficamente recomendado, além de ser desesperadoramente lento (exceto para pequenas quantidades de dados).

Por exemplo, digamos que seu objeto tenha 1 MB. Se você tentar criptografar 1MB com RSA, dividindo a entrada em 8963 blocos de 117 bytes, é muito, muito mais lento que criptografar uma chave AES-256 (são apenas 32 bytes), e criptografar o 1MB de dados com essa chave AES.

Não é aconselhável criptografar repetidos blocos de dados RSA com a mesma chave, porque isso vaza informação sobre a chave.

(Infelizmente, eu li a tal referência bastante tempo atrás e não consigo mais achar essa justificativa. Mas tenho certeza que criptografar muitos blocos de dados com a mesma chave RSA, sendo que os blocos contêm alguma estrutura, é criptograficamente não recomendado.)

Ainda mais que você provavelmente está usando o padding padrão do RSA, que é bem mais frágil que o padding recomendado atualmente (mas que acho ainda não estar implementado pela Sun nessa versão do Java).

merlinX

->Não é aconselhável criptografar repetidos blocos de dados RSA com a mesma chave, porque isso vaza informação sobre a chave.

Se me conseguisse arranjar essa tal referência que justifique esta situação ficava-lhe extremamente grato, visto que gostaria de perceber o porquê.

_

merlinX

Eu estou fazendo uma aplicação que trabalha com certificado gerado pelo keytool utilizando chaves assimétricas e uso classes do pacote [b]javax.crypto [/b].
Encontrei o mesmo problema que você relatou e pelo que parece é isto que é informado neste tópico. Você conseguiu resolver este problema de alguma forma?
Se pudesse gostaria que mostrasse aeh o código pra pegar a chave privada/pública do seu certificado.

Valeu!
Criado 11 de maio de 2009
Ultima resposta 4 de jul. de 2009
Respostas 5
Participantes 3