Criptografia 3DES de senha + hashing MD5 da chave

Ae galera blz ?

To com uma missão aqui… fazer ->
criptografia 3DES de senha + hashing MD5 da chave

procurei bastante aqui no guj sobre, achei algumas boas respostas do nosso amigo thingol, mas ainda to perdidão…

alguem tem algum exemplo ai pra eu me encaminhar???

Muito Obrigado pela força!

Não entendi o que você quer fazer. Se for MD5 de uma senha -> chave para criptografia 3DES, isto está com cara de PBE (Password-Based Encryption).
Se bem que o certo seria que no caso de PBE, a combinação seria outra (PBEWithMD5AndDES ou PBEWithHmacSHA1AndDESede).

Veja mais em http://java.sun.com/j2se/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBE

E ai cara tudo bom !? to meio perdido msm… chegou meu chefe aqui e pediu isso… to tentando procurar algo pra me ajudar…

bom, acho q se encaixa ai na opção (PBEWithMD5AndDES) soh que tinha q usar o 3DES…

vc teria um exxemplo de como eu faria isso ?

por exemplo eu tengo uma chave fixa e a senha assim:

String chave = "evahc";
String password = "henrique";

to tentando mexer num codigo que eu achei aqui no guj…

esse aqui http://www.guj.com.br/posts/list/82586.java#440683

se puder me dar uma ajuda ai fico agradecido !

obrigadão !

Só pra complementar… eu usei esse exempli aqui em baixo e foi blzz… isso mesmo que eu queria… mas tem um porém… como eu uso uma chave fixa, codificada com MD5 nesse codigo abaixo !?

KeyGenerator keygen = KeyGenerator.getInstance("DESede");    
SecretKey desKey = keygen.generateKey();
		
Cipher desCipher;    
// Create the cipher     
desCipher = Cipher.getInstance("DESede");

// Initialize the cipher for encryption    
desCipher.init(Cipher.ENCRYPT_MODE, desKey);    

// Our cleartext    
byte[] cleartext = "henrique".getBytes(); 
System.out.println(new String(cleartext));

// Encrypt the cleartext    
byte[] ciphertext = desCipher.doFinal(cleartext); 
System.out.println(new String(ciphertext));
		 
// Initialize the same cipher for decryption    
desCipher.init(Cipher.DECRYPT_MODE, desKey);    
		 
// Decrypt the ciphertext    
byte[] cleartext1 = desCipher.doFinal(ciphertext);
System.out.println(new String(cleartext1));

abs!

==========>> EDIT <<==========

Galera… fica ai meu codigo para alguem que futuramente estaja com essa duvida…


package com.wincor.prosecurity.beans;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.*;
import java.security.spec.InvalidKeySpecException;

public class Crypto {
	public static final String ALGORITMO_TRIPLE_DES = "DESede";   
	private static Map tamanhosChaves = new HashMap();  
    static {   
        tamanhosChaves.put(ALGORITMO_TRIPLE_DES, new Long(24));              
    }   
	
	public static void main(String[] args) throws InvalidKeyException,
			NoSuchAlgorithmException, InvalidKeySpecException,
			NoSuchPaddingException, IllegalBlockSizeException,
			BadPaddingException, IOException {

		String chave = "KEYkey";
		System.out.println("Chave antes: "+chave);
		chave = encriptaChave(chave);
		System.out.println("Chave MD5: "+chave);
		
		SecretKey skey = getSecretKey(chave, ALGORITMO_TRIPLE_DES); 
		
	//	KeyGenerator keygen = KeyGenerator.getInstance(ALGORITMO_TRIPLE_DES);    
	//	SecretKey desKey = keygen.generateKey();
		
		 Cipher desCipher;    
		 // Create the cipher     
		 desCipher = Cipher.getInstance(ALGORITMO_TRIPLE_DES);
		 // Initialize the cipher for encryption    
		 desCipher.init(Cipher.ENCRYPT_MODE, skey);    
		 // Our cleartext    
		 byte[] cleartext = "senha".getBytes(); 
		 System.out.println("Pass antes: "+new String(cleartext));

		 // Encrypt the cleartext    
		 byte[] ciphertext = desCipher.doFinal(cleartext); 
		 System.out.println("Pass Crip: "+new String(ciphertext));
		 
		 // Initialize the same cipher for decryption    
		 desCipher.init(Cipher.DECRYPT_MODE, skey);    
		 
		 // Decrypt the ciphertext    
		 byte[] cleartext1 = desCipher.doFinal(ciphertext);
		 System.out.println("Pass DesCrip: "+new String(cleartext1));
		
		
	}

	
	public static SecretKey getSecretKey(String chave, String algoritmo) {   
        String keyString =chave;   
        int tam = new Long(tamanhosChaves.get(algoritmo).toString()).intValue();   
        byte[] keyB = new byte[tam];   
        for (int i = 0; i < keyString.length() && i < keyB.length; i++) {   
            keyB[i] = (byte) keyString.charAt(i);   
        }   
        SecretKey skey = new SecretKeySpec(keyB, algoritmo);   
        return skey;   
    }
	
	public static String encriptaChave(String chave) throws NoSuchAlgorithmException{   
        MessageDigest md5=null;   
        md5 = MessageDigest.getInstance("MD5");   
        md5.reset();   
        md5.update(chave.getBytes());   
        return new String(md5.digest());   
    } 
	
	
}

se alguem tiver alguma sugestão ou ponto a levantar soh da um toque !

abs !

Algumas observações:

  • Como thingol já falou (e eu já o citei em outro post): criptografia não é para amadores. :slight_smile:
  • O que você acabou de implementar é exatamente o que faz um PBE.
  • Não trabalhe com String para “transportar” a chave: vai dar problema de encoding.
  • O algoritmo Triple-DES (DESede) suporta vários “modes” (CBC, ECB). Não sei qual o default para o provider padrão de JCE. Se usar um provider diferente ou criptografar usando outra linguagem/plataforma/biblioteca se você vai conseguir descriptografar ou vice-versa.
  • O tamanho “máximo” de uma chave DESede é 168 bits. MD5 gera um hash de 128 bits. Não sei exatamente como é a chave gerada nesta situação.
  • No caso do “plaintext” fixe um encoding (UTF-8 por exemplo) se não vai dar problema na hora de descriptografar.
  • Se for gerar String como output, pense em usar Base64 para não ter problemas.

Amigo… se eu fosse um profissional capacitado em criptografia vc acha que eu ia postar um tópico desse? claro que eu sou amador… Parabens pra vc que deve ser um ótimo especialista no assunto!

Obrigado por ser tão dedicado e prestativo ! :lol:

abs!

[quote=henriquedamota]Amigo… se eu fosse um profissional capacitado em criptografia vc acha que eu ia postar um tópico desse? claro que eu sou amador… Parabens pra vc que deve ser um ótimo especialista no assunto!
brigado por ser tão dedicado e prestativo ! :lol:[/quote]

Senti um certo ironismo na sua resposta!!! :smiley:

Não leve o que eu falei de amador como uma coisa pejorativa. Assim como eu, o thingol também deve ter apanhado bastante com criptografia.
Além disso criptografia é uma assunto que exige uma dedicação para estudo. Se você está começando agora, o que você postou está bem “avançado”. :slight_smile:

De uma estudada em algoritmos de criptografia (o wikipedia é um bom local para achar referencias), message digest ou hash, etc.

okay okay! sem stress vdd ? sexta feira! :slight_smile:

Vc poderia me ajudar melhorar esse código ai mesmo pra deixa ele de um jeito legal, correspondendo as mudanças que vc apontou !?

Uma delas que vc falou ai eu apliquei e não vi diferença(ainda)… que foi isso:

byte[] cleartext = password.getBytes("UTF-8"); 

Obrigado !

Vamos por partes:

  • PBE nada mais é o que você fez: de uma senha gera-se um hash (MD5) que será o seed para chave de criptografia (DESede). Como não existe este padrão implementado na JDK (PBEwithMD5andDESede), aconselho a manter o seu código ou procurar algum provider que o implemente. Se for manter o código tome cuidado com a chave gerada (o problema do tamanho da chave DESede e o hash do MD5). Andei dando uma olhada e em implementações de PBE e o que geralmente se faz é gerar um “salt” para completar a o tamanho da chave. O “salt” ser fixo, pode gerar problemas de segurança (não sei medir o quanto).
  • Se você só for usar o seu código para criptografar e descriptografar (não vai enviar o ciphertext para alguém que vai usar uma outra implementação deste algoritmo) o “mode” do algoritmo de DESede não vai fazer diferença, mas caso seja para trocar mensagens com outros sistemas, você teria que saber qual vai ser o padrão.
  • A questão do Base64 é justamente para evitar o problema de troca de mensagens entre diferentes implementações/sistemas. Nem todo sistema vai entender os caracteres “não printaveis” gerados por um algoritmo de criptografia.

[quote=henriquedamota]
Uma delas que vc falou ai eu apliquei e não vi diferença(ainda)… que foi isso:

byte[] cleartext = password.getBytes("UTF-8"); [/quote]

Seguinte: quando você trabalha com String (independente se está mexendo com criptografia ou não), dependendo do encoding gera-se uma "representação (byte[]) diferente. Se você está trabalhando apenas com caracteres “comuns”, isto fica imperceptivel. Como em criptografia o que importa é o byte[] (que acaba sendo transformado em um número para se aplicar um algoritmo de criptografia) se você gerar o cipherText em uma máquina que tem um encoding e for descriptografar em uma outra que tem um outro encoding, o plainText não vai ser o mesmo.