Problema com chave de segurança do Cipher

11 respostas
danieldestro

Pessoal,
Eu criei uma classe de ciptografia usando o Cipher do javax.crypto. Porém eu tenho um problema com a geração da chave. Eu gero as senhas do usuário no meu BD com um programa. Porém quando vou rodar a aplicação na web, tenho que validar a senha do bando e ele não bate, pois as chaves são diferentes e a criptografia muda. Como posso resolver isso?

Segue o código:

import javax.crypto.*;

/**
 * Esta classe possui método estáticos para fazer criptografia de dados.
 */
public class Criptografia {
	
	private Cipher encCipher;
	private Cipher decCipher;
	
	private static Criptografia instance;
	
	public synchronized static Criptografia getInstance() {
		if( instance == null ) instance = new Criptografia();
		return instance;
	}

	private Criptografia() {
		try {
			SecretKey key = KeyGenerator.getInstance("DES").generateKey();
			encCipher = Cipher.getInstance("DES");
			decCipher = Cipher.getInstance("DES");
			encCipher.init(Cipher.ENCRYPT_MODE, key);
			decCipher.init(Cipher.DECRYPT_MODE, key);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String cryptDES( String data ) throws Exception {
		try {
			// Encode the string into bytes using utf-8
			byte[] bytes = data.getBytes();
			// Encrypt
			byte[] enc = encCipher.doFinal(bytes);
			// Encode bytes to base64 to get a string
			return new sun.misc.BASE64Encoder().encode(enc);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String decryptDES( String encrypted ) throws Exception {
		try {
			// Decode base64 to get bytes
			byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
			// Decrypt
			byte[] bytes = decCipher.doFinal(dec);
			return new String(bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

11 Respostas

maxguzenski

seu problema é de UNICODE, ja tive isso… sofri pra resolver :slight_smile:

seguinte, compara o numeros gerados do array de bytes (em bytes mesmo, nao transforme pra char) com os gerados pelo String.getBytes()

voce vai ver que alguns nao sao iguais, embora os caracteres sejam os mesmos. :slight_smile:

danieldestro

Eu comentei a parte do Decode64…

O que eu acho é que cada vez que o programa é executado, a chave muda, portanto muda a encriptação e desencriptação.

LOUDS??? Ajude-meeeeee…

maxguzenski

ah, isso tbm…
mas voce pode passar uma chave constante para o DES.

maxguzenski

mas mesmo assim, nao confie na estoria de ficar invertendo entre byte[] e String, ja tive problemas com isso

danieldestro

Essa chave pode ser qualquer ? Tem um padrão ?

Não achei nada sobre isso !

maxguzenski

quanto menos padrao melhor :slight_smile:
vale tudo, menos usar o Random , pois ele nao gera numeros bons para criptografia… use o SecureRandom …

cara, nao tenho o codigo aqui agora, mas amanha eu acho q te mostro um exemplo…

danieldestro

To aguardando, carinha!

Só preciso ver como ter uma chave que posso usar em qualquer aplicação.

louds

Voce tem que usar a mesma chave Em todas operações.

Para salvar a chave basta serializar ela ou usar o método getEncoded(). O primeiro é trivial de recuperar, o segundo exige o uso de uma KeyStore.

velo

danieldestro:

..... private Cipher encCipher; private Cipher decCipher; .....

Pessoal, me digam uma coisa, como posso serializar a chave encCipher?

public class Chave implements Serializable { private Cipher chave; public Chave(Cipher chave) { this.chave = chave; } public Cipher getChave() { return chave; } }

Tentei fazer isso, mas ainda assim lança exception na hora de enviar via socket:

<blockquote>java.io.NotSerializableException: javax.crypto.Cipher

at java.io.ObjectOutputStream.writeObject0(Unknown Source)

at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)

at java.io.ObjectOutputStream.writeSerialData(Unknown Source)

at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)

at java.io.ObjectOutputStream.writeObject0(Unknown Source)

at java.io.ObjectOutputStream.writeObject(Unknown Source)

at projeto.UsuariosServer.<init>(UsuariosServer.java:74)

at projeto.UsuariosServer.main(UsuariosServer.java:215)</blockquote>

Se alguem tiver uma ideia, sou todo ouvidos.

PS: Estou tentando transmitir a chave via socket e criptografar alguns dados no cliente.

VELO

T

Destro-san, veja o exemplo no post (usei IDEA, mas você pode usar outro algoritmo.) Acho que você está com problemas de usar a chave.

No post está sendo usado o BouncyCastle, mas se você usar um algoritmo suportado pelo JCE normal, o exemplo pode ser usado sem o BouncyCastle.

http://www.guj.com.br/posts/list/18669.java

Você não pode serializar javax.crypto.Cipher, mas pode usar a codificação em bytes (veja .getEncoded() e SecretKeySpec)

Obviamente para transmitir a chave são outros quinhentos, se for o caso use PBE (Password-Based Encryption), procure PBE na lista de algoritmos.

velo

eh, mas assim eu vou mandar o bolo inteiro…

Eu queria mandar apenas a chave que criptografa, e guarda a que decriptografa no servidor…

Bom, se alguem tiver uma ideia, estamos aih.

VELO

Criado 11 de março de 2004
Ultima resposta 22 de dez. de 2004
Respostas 11
Participantes 5