Erro Casting Object to SealedObject

17 respostas
_

Galera do GUJ,

Estou recebendo a seguinte mensgem de erro:

Exception in thread "Chat" java.lang.ClassCastException: java.lang.String cannot be cast to javax.crypto.SealedObject
	at DecryptMsg.decrypt(DecryptMsg.java:51)
	at GrafClient$Reader.run(GrafClient.java:268)

A linha do erro (linha 51) está em negrito e marcada como comentário.

Os códigos que estão envolvidos com a mensagem acima estão logo abaixo:

public class Reader extends Thread {
		
	    protected GrafClient cliente;
	    private JTextArea OutputArea;
		  
	    public Reader(GrafClient c, JTextArea OutputArea) {
		
	       super("Chat");
	       this.cliente=c;
	       this.OutputArea = OutputArea;
	    }

	    public void run()  {
		
	      DataInputStream in = null;
	      String line, result = "";		  
	      Object objcif;
			  
	      try {
		      
	         in = new DataInputStream(cliente.clisoc.getInputStream());
		    
	         while(true){
		    	  
	              line = in.readLine();
       	              objcif = line;
	              result = DecryptMsg.decrypt(key2, objcif);
	              OutputArea.append(name + "> " +result +"\r\n");
	          }
	
     	      } catch(IOException e) {
	           System.out.println("Reader:"+e);
	      }
	}
           }
public static String decrypt(PrivateKey privk, Object objcif) {
		    
	    Cipher c;
	    String s ="";	
	    SealedObject objcifrado;
	    	   
	    try {
	    	
	    	c = Cipher.getInstance("RSA");
	    	c.init(Cipher.DECRYPT_MODE, privk);
                                // linha do erro (51)
	    	[b]objcifrado = (SealedObject) objcif;[/b]
	    	s = (String)objcifrado.getObject(c); 
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return s;

		 
	}

Neste caso eu envio um objeto tipo SealedObject criptografado para o Servidor e depois que recebo dele para assim descriptografá-lo e assim compreender a mensagem.

Raphael

17 Respostas

Fox_McCloud

Isso me parece bem simples…

A linha DecryptMsg.decrypt(key2, objcif); grava uma String no seu atributo Object objcif;

Não se pode efetuar casting de String para SealedObject porque String não é (não extende em nenhum nível) SealedObject…

Veja bem de onde vc tirou esse algoritmo pra saber como você coloca a sua String dentro do SealedObject…

:wink:

_

Haveria alguma outra condição ou opção pra resolver este problema?

No aguardo…

Raphael

Fox_McCloud

Bom, de onde vem a classe DecryptMsg?

rapha:

Haveria alguma outra condição ou opção pra resolver este problema?

No aguardo…

Raphael

_

A classe DecryptMsg é uma classe separada que implementa o método decrypt, que tem objetivo de : utilizando a chave privada do usuário, fazer a descriptografia do objeto criptografado SealedObject.

Raphael

Fox_McCloud

Então, sem conhecer o método eu não posso te esclarecer o que acontece. Só sei que o método em questão grava uma String na referência recebida!

:wink:

rapha:

A classe DecryptMsg é uma classe separada que implementa o método decrypt, que tem objetivo de : utilizando a chave privada do usuário, fazer a descriptografia do objeto criptografado SealedObject.

Raphael

_

O que o método realiza está informado no início do tópico. Precisa ver mais alguma coisa?

T

Amigo, leia a documentação antes de ficar desesperado.

Se tivesse lido adequadamente a documentação de SealedObject, teria visto que há um método getObject que faz exatamente o que você precisa.

SealedObject

E não se esqueça - repita comigo (de preferência usando um terço, para poder contar 100 vezes): cast não faz conversão em Java.

Fox_McCloud

Ahuahuahuahua, lembrei do Bart Simpson na lousa agora…

É verdade… então veja essa linha:

s = (String)objcifrado.getObject(c);

Claramente o objeto devolvido é uma String, somente por isso o casting (String) não causa uma ClassCastingException, vide o que o Thingol disse, mas esse objeto nunca será diferente de uma String (um SealedObject, por exemplo).

Agora veja a linha anterior:

objcifrado = (SealedObject) objcif;

Veja que o SealedObject é o objcif (senão haveria também uma ClassCastingException, vide o que o Thingol disse)… então, somando 1 + 1…

O objcifrado contém uma String. O método está devolvendo essa String, não o próprio SealedObject.

Pense mais um pouco com calma… você está perto de desvendar o mistério!

:wink:

_

Valeu Thingol… mas não vou rezar não. Já entendi a questão. E não estou desesperado também não. Estou só querendo entender a questão que estou tentando explicar. Eu já tinha lido uma parte da documentação do SealedObject, mas então o método que você cita pode resolver tudo q preciso?
Então… vou pensar mais um pouco Fox McCloud, mas pode me dar uma luz agora?

_

Eu recebo uma String do servidor e armazeno na variável line como está logo abaixo:

line = in.readLine();
Detalhe importante... um dos parâmetros que devo passar para o método decrypt é do tipo SealedObject, que no caso é o objeto que foi encriptado por outro método [i]encrypt[/i]. No caso eu recebo uma String e não um SealedObject.

Podem me dar a luz que preciso?

Raphael
T

Construtor SealedObject

Como toda String implementa Serializable…

_

Thingol ainda não está claro por sua explicação. Acredito que entendeu o que expliquei. Seja mais claro e me mostre como posso fazer.

T

Basicamente você quer saber como é que se chega a uma String, dado um SealedObject, e como se chega a um SealedObject, dada uma String.

A ideia é que um SealedObject é equivalente ao objeto original, só que criptografado. Para tanto, você precisa de uma forma de cifrar ou decifrar os dados.

Quando você usa o construtor de SealedObject que recebe um objeto qualquer que possa ser serializado, o que o tal construtor faz? Ele pega o tal objeto, efetua sua serialização para um array de bytes, cifra-o usando o objeto do tipo Cipher que você passou como parâmetro, e então monta o tal objeto SealedObject.

Quando você usa o método getObject de SealedObject, que recebe um Cipher como parâmetro, ele decifra um array de bytes que ele tem internamente, e então “desserializa” para um objeto equivalente ao objeto original (que seria uma String).

_

Valeu Thingol. Vou testar aqui.

Qualquer dúvida se não achar ruim, volto a perguntar aqui novamente.

Raphael

_

O Thingol… aproveitando mais um pouco. Me dá uma luz como posso fazer a nível de código essa parte.

Eu preciso de um objeto tipo SealedObject para enviar para o meu método decrypt e assim retornar o objeto ao estado original (descriptografar).

Valeu

T

Um exemplo bobo, usando SealedObject. Não posso resolver o seu problema em particular, mas você pode usar isto como referência.

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;


class ExemploGeracaoParChavesRSA {
    public KeyPair generateKeyPair () throws NoSuchAlgorithmException {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance ("RSA");
        kpg.initialize (1024);
        kp = kpg.generateKeyPair ();
        return kp;
    }
    public Cipher getEncryptingCipher () throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance ("RSA");
        cipher.init (Cipher.ENCRYPT_MODE, kp.getPublic ());
        return cipher;
    }
    public Cipher getDecryptingCipher () throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        Cipher cipher = Cipher.getInstance ("RSA");
        cipher.init (Cipher.DECRYPT_MODE, kp.getPrivate ());
        return cipher;
    }
    private KeyPair kp;
}

/**
 *
 */
public class ExemploSealedObject {
    public String decrypt (SealedObject so) throws IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException {
        return (String) so.getObject (decryptingCipher);
    }
    public SealedObject encrypt (String str) throws IOException, IllegalBlockSizeException {
        return new SealedObject (str, encryptingCipher);
    }
    public void setEncryptingCipher (final Cipher encryptingCipher_) {
        encryptingCipher = encryptingCipher_;
    }
    public void setDecryptingCipher (final Cipher decryptingCipher_) {
        decryptingCipher = decryptingCipher_;
    }
    private Cipher encryptingCipher;
    private Cipher decryptingCipher;

    public static void main (String[] args) throws Exception {
        ExemploSealedObject eso1 = new ExemploSealedObject();
        ExemploSealedObject eso2 = new ExemploSealedObject();
        Cipher encryptingCipher;
        Cipher decryptingCipher;
        // Vamos criar um par de chaves RSA, só para ver como é.
        // Você poderia pegar a chave do keystore, por exemplo. 
        ExemploGeracaoParChavesRSA ex = new ExemploGeracaoParChavesRSA();
        ex.generateKeyPair ();
        encryptingCipher = ex.getEncryptingCipher ();
        decryptingCipher = ex.getDecryptingCipher ();
        eso1.setEncryptingCipher (encryptingCipher);
        SealedObject so = eso1.encrypt ("Hello, world!");
        eso2.setDecryptingCipher (decryptingCipher);
        String str = eso2.decrypt (so);
        System.out.println (str);
        // Saída esperada:
        // "Hello, world!"
    }
}
_

OK Thingol. Mas só pra entender. Porque não pode resolver este meu problema ?

Raphael

Criado 19 de julho de 2009
Ultima resposta 22 de jul. de 2009
Respostas 17
Participantes 3