Método de criptografia e descriptografia que funcione! (Resolvido)

E ae pessoal.

Eu tenho um arquivo XML que guarda as informações para conexão com o banco de dados. Mas como o XML é super inseguro, pensei em criptografar pelo menos a senha que está na tag . Procurei na net e achei uma classe que faz isso, usando DES. Fiz um teste e funcionou perfeitamente como eu queria. Fiz outro teste gravando no XML a senha criptografada e funcionou. Mas quando eu quero descriptografar ela, retorna o seguinte erro:

[quote]javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*…)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*…)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*…)
at javax.crypto.Cipher.doFinal(DashoA13*…)
at classes.Kriptonita.decriptar(Kriptonita.java:92)
at gui.Configuracoes.(Configuracoes.java:55)
at gui.Principal.btConfigActionPerformed(Principal.java:265)
at gui.Principal.access$300(Principal.java:18)
at gui.Principal$4.actionPerformed(Principal.java:126)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)[/quote]

Pesquisei em tudo que é lugar e não encontrei uma solução eficaz. Alguém sabe como resolver isso ou tem algum algoritmo de criptografia e descriptografia eficaz?

Segue a classe que eu adaptei:

[code]/*

  • Cript.java
  • Created on 22 de Outubro de 2007, 21:26
    */

package classes;

// Imports necessarios
import java.security.;
import javax.crypto.
;
import java.io.*;

/**

  • Classe que criptografa e descriptografa uma String

  • @version 1.0

  • @author Anderson
    */
    public class Kriptonita {
    // Variaveis privadas da classe
    private Cipher ecipher;
    private Cipher dcipher;

    /**

    • Construtor da classe que cria uma chave criptografada do tipo DES

    • @version 1.0

    • @author Anderson
      */
      public Kriptonita() {
      try {
      SecretKey chave = KeyGenerator.getInstance(“DES”).generateKey();

       ecipher = Cipher.getInstance("DES");
       dcipher = Cipher.getInstance("DES");
       ecipher.init(Cipher.ENCRYPT_MODE, chave);
       dcipher.init(Cipher.DECRYPT_MODE, chave);
      

      } catch (InvalidKeyException ex) {
      ex.printStackTrace();
      } catch (NoSuchPaddingException ex) {
      ex.printStackTrace();
      } catch (NoSuchAlgorithmException ex) {
      ex.printStackTrace();
      }
      }

    /**

    • Metodo que faz a criptografia de uma String em 64 bits

    • @param str Pega a string que sera criptograda

    • @return Retorna a String criptografada

    • @version 1.0

    • @author Anderson
      */
      public String encriptar(String str) {
      try {
      // Codifica a String usando UTF-8
      byte[] utf8 = str.getBytes(“UTF-8”);

       // Encripta
       byte[] enc = ecipher.doFinal(utf8);
      
       // Codifica os bytes usando Base64
       return new sun.misc.BASE64Encoder().encode(enc);
      

      } catch (javax.crypto.BadPaddingException ex) {
      ex.printStackTrace();
      } catch (IllegalBlockSizeException ex) {
      ex.printStackTrace();
      } catch (UnsupportedEncodingException ex) {
      ex.printStackTrace();
      } catch (java.io.IOException ex) {
      ex.printStackTrace();
      }

      // Caso nao consiga, retorna null
      return null;
      }

    /**

    • Metodo que decriptografa uma String que foi criptografada em 64 bits

    • @param str Pega a String criptografada para volta-la ao formato UTF-8

    • @return Retorna a String decriptografa no formato UTF-8

    • @version 1.0

    • @author Anderson
      */
      public String decriptar(String str) {
      try {
      // Decodifica na base64 os bytes capturados
      byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);

       // Decripta
       byte[] utf8 = dcipher.doFinal(dec);
      
       // Decodifica usando UTF-8
       return new String(utf8, "UTF-8");
      

      } catch (javax.crypto.BadPaddingException ex) {
      ex.printStackTrace();
      } catch (IllegalBlockSizeException ex) {
      ex.printStackTrace();
      } catch (UnsupportedEncodingException ex) {
      ex.printStackTrace();
      } catch (java.io.IOException ex) {
      ex.printStackTrace();
      }

      // Caso nao consiga, retorna null
      return null;
      }

}
[/code]

Agradeço muito a ajuda de vocês.

Abraços.

Quando você usa “DES” na verdade está usando “DES/ECB/NoPadding” se não me engano. Nesse caso pode dar problemas se a entrada não for um múltiplo de 8 bytes.

Tente com “DES/CBC/PKCS7Padding” (cuidado porque a saída é sempre um múltiplo de 8 bytes (ou é o tamanho original, acrescentado de 8), e você tem de estar preparado para isso.
Se sua entrada tiver 7 bytes, o resultado criptografado tem 8, e se sua entrada tiver 8 bytes, o resultado criptografado tem 16.

Dica: procure aqui no fórum um programa que escrevi que usa “PBEWithMD5AndDES”. Ele permite criptografia com senha e já deixa o resultado codificado bonitinho em Base-64.

Humm, eu mudei o construtor e quando eu peço para Salvar, me da esse erro:

[quote]java.security.NoSuchAlgorithmException: Cannot find any provider supporting DES/CBC/PKCS7Padding
at javax.crypto.Cipher.getInstance(DashoA13*…)
at classes.Kriptonita.(Kriptonita.java:33)
at gui.Configuracoes.(Configuracoes.java:46)
at gui.Principal.btConfigActionPerformed(Principal.java:265)
at gui.Principal.access$300(Principal.java:18)
at gui.Principal$4.actionPerformed(Principal.java:126)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)[/quote]

Eu fiz o construtor assim:

[code]public Kriptonita() {
try {
SecretKey chave = KeyGenerator.getInstance(“DES”).generateKey();

        ecipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
        dcipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
        ecipher.init(Cipher.ENCRYPT_MODE, chave);
        dcipher.init(Cipher.DECRYPT_MODE, chave);
    } catch (InvalidKeyException ex) {
        ex.printStackTrace();
    } catch (NoSuchPaddingException ex) {
        ex.printStackTrace();
    } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
    }
}[/code]

O que está errado?

Desculpe, é “DES/CBC/PKCS5Padding”. Não sei porque pus 7 em vez de 5.

Valeu thingol, mas agora olha que estranho, está faltando parâmetros:

[code]public Kriptonita() {
try {
SecretKey chave = KeyGenerator.getInstance(“DES”).generateKey();

        ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        ecipher.init(Cipher.ENCRYPT_MODE, chave);
        dcipher.init(Cipher.DECRYPT_MODE, chave);
    } catch (InvalidKeyException ex) {
        ex.printStackTrace();
    } catch (NoSuchPaddingException ex) {
        ex.printStackTrace();
    } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
    }
}[/code]

E o erro retorna:

[quote]java.security.InvalidKeyException: Parameters missing
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*…)
at com.sun.crypto.provider.DESCipher.engineInit(DashoA13*…)
at javax.crypto.Cipher.a(DashoA13*…)
at javax.crypto.Cipher.a(DashoA13*…)
at javax.crypto.Cipher.init(DashoA13*…)
at javax.crypto.Cipher.init(DashoA13*…)
at classes.Kriptonita.(Kriptonita.java:36)
at gui.Configuracoes.(Configuracoes.java:46)
at gui.Principal.btConfigActionPerformed(Principal.java:265)
at gui.Principal.access$300(Principal.java:18)
at gui.Principal$4.actionPerformed(Principal.java:126)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)[/quote]

Nossa, como é xarope isso hehehehehe. Eu não achei o seu programa. Você pode mandar pra mim por e-mail?

Vou postar de novo. Eu tinha feito para senhas de bancos de dados, mas serve também para o seu caso (que é um XML).

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.KeySpec;
import sun.misc.BASE64Encoder; // para simplificar o exemplo. Use alguma outra classe para converter
import sun.misc.BASE64Decoder; // para Base-64.
public final class PWSec {
    private static SecretKey skey;
    private static KeySpec ks;
    private static PBEParameterSpec ps;
    private static final String algorithm = "PBEWithMD5AndDES";
    private static BASE64Encoder enc = new BASE64Encoder();
    private static BASE64Decoder dec = new BASE64Decoder();
    static {
        try {
            SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
            ps = new PBEParameterSpec (new byte[]{3,1,4,1,5,9,2,6}, 20);

            ks = new PBEKeySpec ("EAlGeEen3/m8/YkO".toCharArray()); // esta ? a chave que voc? quer manter secreta.
            // Obviamente quando voc? for implantar na sua empresa, use alguma outra coisa - por exemplo,
            // "05Bc5hswRWpwp1sew+MSoHcj28rQ0MK8". Nao use caracteres especiais (como ?) para nao dar problemas.

            skey = skf.generateSecret (ks);
        } catch (java.security.NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (java.security.spec.InvalidKeySpecException ex) {
            ex.printStackTrace();
        }
    }
    public static final String encrypt(final String text)
        throws
        BadPaddingException,
        NoSuchPaddingException,
        IllegalBlockSizeException,
        InvalidKeyException,
        NoSuchAlgorithmException,
        InvalidAlgorithmParameterException {
            
        final Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, skey, ps);
        return enc.encode (cipher.doFinal(text.getBytes()));
    }
    public static final String decrypt(final String text)
        throws
        BadPaddingException,
        NoSuchPaddingException,
        IllegalBlockSizeException,
        InvalidKeyException,
        NoSuchAlgorithmException,
        InvalidAlgorithmParameterException {
            
        final Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, skey, ps);
        String ret = null;
        try {
            ret = new String(cipher.doFinal(dec.decodeBuffer (text)));
        } catch (Exception ex) {
        }
        return ret;
    }
    public static void main(String[] args) throws Exception {
        String password = "3p6/Lsbp+MIK8zqK"; // esta ? a tal senha do banco de dados que voc? quer criptografar
        String encoded = PWSec.encrypt (password);
        System.out.println (encoded);  // imprime "4fWCjTdEhMPEluqE2n8ci4FiqWeb+DXc"
        System.out.println (PWSec.decrypt (encoded).equals (password)); // imprime "true"
        // Vamos alterar um caracter, s¢ para ver o que ocorre
        char[] enc = encoded.toCharArray();
        enc[2] = (char) (enc[2] + 1);
        encoded = new String (enc);
        System.out.println (encoded); // imprime "4fXCjTdEhMPEluqE2n8ci4FiqWeb+DXc"
        System.out.println (password.equals (PWSec.decrypt (encoded))); // imprime "false"
    }
}

Valeu thingol, já rodei o código, agora eu vou testar com meu XML, qualquer coisa eu posto aqui.

Obrigado pela força.

Abraços.

[quote=Pilantra]Valeu thingol, já rodei o código, agora eu vou testar com meu XML, qualquer coisa eu posto aqui.

Obrigado pela força.

Abraços.[/quote]

Nossa, funcionou perfeitamente cara. Muito obrigado mesmo, essa classe vale ouro hehehe…

Abraços.

Pilantra

Valeu pela dica. Me poupou umas horas para desenvolver.

Valeu mesmo

Olá Galera,
eu sei q este
tópico já está off,
mas thingol era essa
a classe q eu precisava,
mas estou com algumas
dúvidas pq na linha 13 vc fla:
// para simplificar o exemplo. Use alguma outra classe para converter
base 64 é pq o algoritmo é de 64 bits?

Base-64 é uma forma de codificação de dados binários.

Jóia thingol,
Obrigado pela
ajuda, mas
na linha 13
o q vc quis dizer
com o comentário

// para simplificar o exemplo. Use alguma outra classe para converter para Base-64?

mas no código eu já ñ uso a base-64 para criptografar?
Abraço.

[quote=thingol]Vou postar de novo. Eu tinha feito para senhas de bancos de dados, mas serve também para o seu caso (que é um XML).

[code]
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.crypto.;
import javax.crypto.spec.
;
import java.security.;
import java.security.spec.
;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.KeySpec;
import sun.misc.BASE64Encoder; // para simplificar o exemplo. Use alguma outra classe para converter
import sun.misc.BASE64Decoder; // para Base-64.
public final class PWSec {
private static SecretKey skey;
private static KeySpec ks;
private static PBEParameterSpec ps;
private static final String algorithm = “PBEWithMD5AndDES”;
private static BASE64Encoder enc = new BASE64Encoder();
private static BASE64Decoder dec = new BASE64Decoder();
static {
try {
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
ps = new PBEParameterSpec (new byte[]{3,1,4,1,5,9,2,6}, 20);

        ks = new PBEKeySpec ("EAlGeEen3/m8/YkO".toCharArray()); // esta ? a chave que voc? quer manter secreta.
        // Obviamente quando voc? for implantar na sua empresa, use alguma outra coisa - por exemplo,
        // "05Bc5hswRWpwp1sew+MSoHcj28rQ0MK8". Nao use caracteres especiais (como ?) para nao dar problemas.

        skey = skf.generateSecret (ks);
    } catch (java.security.NoSuchAlgorithmException ex) {
        ex.printStackTrace();
    } catch (java.security.spec.InvalidKeySpecException ex) {
        ex.printStackTrace();
    }
}
public static final String encrypt(final String text)
    throws
    BadPaddingException,
    NoSuchPaddingException,
    IllegalBlockSizeException,
    InvalidKeyException,
    NoSuchAlgorithmException,
    InvalidAlgorithmParameterException {
        
    final Cipher cipher = Cipher.getInstance(algorithm);
    cipher.init(Cipher.ENCRYPT_MODE, skey, ps);
    return enc.encode (cipher.doFinal(text.getBytes()));
}
public static final String decrypt(final String text)
    throws
    BadPaddingException,
    NoSuchPaddingException,
    IllegalBlockSizeException,
    InvalidKeyException,
    NoSuchAlgorithmException,
    InvalidAlgorithmParameterException {
        
    final Cipher cipher = Cipher.getInstance(algorithm);
    cipher.init(Cipher.DECRYPT_MODE, skey, ps);
    String ret = null;
    try {
        ret = new String(cipher.doFinal(dec.decodeBuffer (text)));
    } catch (Exception ex) {
    }
    return ret;
}
public static void main(String[] args) throws Exception {
    String password = "3p6/Lsbp+MIK8zqK"; // esta ? a tal senha do banco de dados que voc? quer criptografar
    String encoded = PWSec.encrypt (password);
    System.out.println (encoded);  // imprime "4fWCjTdEhMPEluqE2n8ci4FiqWeb+DXc"
    System.out.println (PWSec.decrypt (encoded).equals (password)); // imprime "true"
    // Vamos alterar um caracter, s¢ para ver o que ocorre
    char[] enc = encoded.toCharArray();
    enc[2] = (char) (enc[2] + 1);
    encoded = new String (enc);
    System.out.println (encoded); // imprime "4fXCjTdEhMPEluqE2n8ci4FiqWeb+DXc"
    System.out.println (password.equals (PWSec.decrypt (encoded))); // imprime "false"
}

}

[/code][/quote]

Olá…
thingol, muito boa essa classe ai para criptografia… ajudou muito cara… obrigado…
Tenho dúvida com relação ao ‘salt’, eu sei pra que serve mas não sei como se implementa…
Só gostaria de saber se o tal do ‘salt’ (salto) está presente nessa classe ai que você implementou?
Caso essa classe não possua o ‘salt’ poderia me dar um exemplo de como implementar?
Desde já muito obrigado…

:frowning: ???

Por favor… alguém??

Parabéns !! Muito bom o post !!!

Precisamos de colabores assim em foruns !!

Abraços,

Fabio Santos