[Resolvido] Rijndael em java

Ola pessoal, desde já agradeço pelo fórum, pois já salvou minha pele por varias vezes…
Seguinte…
Estou tendo que consumir um Webservice em C# onde vai trafegar um xml criptografado no modelo Rijndael, já procurei mas não estou encontrando como fazer a criptografia e a descriptografia no modelo Rijndael em java, será que tem alguma API pra isso? alguém poderia me dar uma luz por favor?

Valew galera… Abraços…

Vê se te ajuda: http://stackoverflow.com/questions/587357/rijndael-support-in-java

talvez te ajude
https://gist.github.com/1080133
http://n3vrax.wordpress.com/2011/08/14/aesrijndael-java-implementation/

Obrigado pessoal, vi os links, mas a criptografia não bate com a do C#…
Estive pesquisando e encontrei algo a respeito do BouncyCastle, alguém teria algum exemplo desta implementação, para que eu siga como base?
Obrigado

Encontrei o jasypt também alguém já usou, será que resolve?

falow

O Rijndael (C#) é a mesma coisa que o AES (Java), só que aqueles parâmetros criptográficos (tamanho da chave, vetor de inicialização e modo criptográfico) são especificados de forma um pouco diferente.

Não é impossível decifrar com Java algo que foi criptografado com C# ; a parte chata é saber exatamente como é que foi escrita a aplicação em C# para que possamos escrever o equivalente em Java.

O jasypt é um encapsulamento da JCE (APIs de criptografia do Java), com alguns parâmetros mais usados já predeterminados. Não sei se isso vai lhe resolver o problema, porque não tenho o seu programa C# original que gerou os dados criptografados.
O BouncyCastle é uma implementação da JCE, e também implementa um monte de APIs adicionais, que são essenciais para lidar com os formatos mais usados.

Eu chutaria que, dependendo dos parâmetros que foram usados para criptografar os dados, não precise de mais nada que esteja fora do JDK.

O legal entanglement, muito obrigado. e que o programa em C# e de uma outra empresa, mas acabei de pegar la o código usado la por ele.

[code]using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Seguranca
{
static class ClSeguranca
{
static string CONST_CHAVE = “Chave_Exemplo”;

    public static string Criptografar(string dados)  
    {  
        string chave = CONST_CHAVE;  
        byte[] b = Encoding.UTF8.GetBytes(dados);  
        byte[] pw = Encoding.UTF8.GetBytes(chave);  

        RijndaelManaged rm = new RijndaelManaged();  
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(chave, new MD5CryptoServiceProvider().ComputeHash(pw));  
        rm.Key = pdb.GetBytes(32);  
        rm.IV = pdb.GetBytes(16);  
        rm.BlockSize = 128;  
        rm.Padding = PaddingMode.PKCS7;  

        MemoryStream ms = new MemoryStream();  

        CryptoStream cryptStream = new CryptoStream(ms, rm.CreateEncryptor(rm.Key, rm.IV), CryptoStreamMode.Write);  
        cryptStream.Write(b, 0, b.Length);  
        cryptStream.FlushFinalBlock();  


        return System.Convert.ToBase64String(ms.ToArray());   

    }  

    public static string Descriptografar(string  sDados)  
    {  
        string chave = CONST_CHAVE;  
        byte[] dados = System.Convert.FromBase64String(sDados);  
        byte[] pw = Encoding.UTF8.GetBytes(chave);  

        RijndaelManaged rm = new RijndaelManaged();  
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(chave, new MD5CryptoServiceProvider().ComputeHash(pw));  
        rm.Key = pdb.GetBytes(32);  
        rm.IV = pdb.GetBytes(16);  
        rm.BlockSize = 128;  
        rm.Padding = PaddingMode.PKCS7;  

        MemoryStream ms = new MemoryStream(dados, 0, dados.Length);  

        CryptoStream cryptStream = new CryptoStream(ms, rm.CreateDecryptor(rm.Key, rm.IV), CryptoStreamMode.Read);  
        StreamReader sr = new StreamReader(cryptStream);  

        return sr.ReadToEnd();  
      
    }  
}  

} [/code]

Agora como fazer isso em java, tentei de vários jeito até consegui a criptografia mas não bateu com a dele.

Caso vc tenha alguma ideia e puder me ajudar, agradeço.

Valew

Hum, acho que seu problema está, na verdade, aqui:

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(chave, new MD5CryptoServiceProvider().ComputeHash(pw)); 

Não estou conseguindo seguir a thread referenciada aqui, porque o proxy aqui bloqueia o nabble.com:
http://stackoverflow.com/questions/2121047/java-encode-and-net-decode

http://old.nabble.com/.NET-PasswordDeriveBytes-tt9114084.html#a9114084

Basicamente, PasswordDeriveBytes (C#) usa um algoritmo (PBKDF1) e PBEKeySpec (Java) usa outro algoritmo (PBKDF2).

Não consegui fazer bater a criptografia.
Agora estamos tentando usar o 3DES mas mesmo assim não está rolando.

código c# Resultado = l2DWkv2JTeM=

  public class Criptografia
    {
        private static byte[] GetKey(string password)
        {
            string pwd = null;

            if (Encoding.UTF8.GetByteCount(password) < 24)
                pwd = password.PadRight(24, ' ');
            else
                pwd = password.Substring(0, 24);

            return Encoding.UTF8.GetBytes(pwd);
        }

        public static string Encrypt(string data, string password)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
            DES.Mode = CipherMode.ECB;
            DES.Key = GetKey(password);

            DES.Padding = PaddingMode.PKCS7;
            ICryptoTransform DESEncrypt = DES.CreateEncryptor();
            Byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);

            return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }

        public static string Decrypt(string data, string password)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
            DES.Mode = CipherMode.ECB;
            DES.Key = GetKey(password);

            DES.Padding = PaddingMode.PKCS7;
            ICryptoTransform DESEncrypt = DES.CreateDecryptor();
            Byte[] Buffer = Convert.FromBase64String(data);

            return Encoding.UTF8.GetString(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }
    }

Código em java com BouncyCastle Resultado = l2DWkv2JTeM=

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.misc.BASE64Encoder;

public class TripleDesBouncyCastle {
	private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/PKCS7Padding";
	private static String ALGORITHM = "DESede";
	private static String BOUNCY_CASTLE_PROVIDER = "BC";

	private static void init() {
		Security.addProvider(new BouncyCastleProvider());
	}

	public static byte[] encode(byte[] input, byte[] key)
			throws IllegalBlockSizeException, BadPaddingException,
			NoSuchAlgorithmException, NoSuchProviderException,
			NoSuchPaddingException, InvalidKeyException {
		init();
		SecretKey keySpec = new SecretKeySpec(key, ALGORITHM);
		Cipher encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION,
				BOUNCY_CASTLE_PROVIDER);
		encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
		return encrypter.doFinal(input);
	}

	public static byte[] decode(byte[] input, byte[] key)
			throws IllegalBlockSizeException, BadPaddingException,
			NoSuchAlgorithmException, NoSuchProviderException,
			NoSuchPaddingException, InvalidKeyException {
		init();
		SecretKey keySpec = new SecretKeySpec(key, ALGORITHM);
		Cipher decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION,
				BOUNCY_CASTLE_PROVIDER);
		decrypter.init(Cipher.DECRYPT_MODE, keySpec);
		return decrypter.doFinal(input);
	}

	public static void main(String[] args) throws IOException,
			InvalidKeyException, IllegalBlockSizeException,
			BadPaddingException, NoSuchAlgorithmException,
			NoSuchProviderException, NoSuchPaddingException {

		String texto = "teste";
		String chave = "12345678ABCDEFGHHGFEDCBA";

		BASE64Encoder enc = new BASE64Encoder();

		byte[] result = encode(texto.getBytes(), chave.getBytes());
		System.out.println(enc.encode(result));

	}
}

Códogo em Java ( API padrão) Resultado = kQ32PSfsgJ4=

import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;

public class TripleDESTest {

    public static void main(String[] args) throws Exception {

    	String text = "teste";

    	byte[] codedtext = new TripleDESTest().encrypt(text);
    	String decodedtext = new TripleDESTest().decrypt(codedtext);

    	System.out.println(new BASE64Encoder().encode(codedtext)); // this is a byte array, you'll just see a reference to an array
    	System.out.println(decodedtext); // This correctly shows "kyle boon"
    }

    public byte[] encrypt(String message) throws Exception {
    	final MessageDigest md = MessageDigest.getInstance("md5");
    	final byte[] digestOfPassword = md.digest("12345678ABCDEFGHHGFEDCBA".getBytes("utf-8"));
    	final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    	for (int j = 0, k = 16; j < 8;) {
    		keyBytes[k++] = keyBytes[j++];
    	}

    	final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
    	final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    	final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    	cipher.init(Cipher.ENCRYPT_MODE, key);

    	final byte[] plainTextBytes = message.getBytes("utf-8");
    	final byte[] cipherText = cipher.doFinal(plainTextBytes);
    	// final String encodedCipherText = new sun.misc.BASE64Encoder()
    	// .encode(cipherText);

    	return cipherText;
    }

    public String decrypt(byte[] message) throws Exception {
    	final MessageDigest md = MessageDigest.getInstance("md5");
    	final byte[] digestOfPassword = md.digest("12345678ABCDEFGHHGFEDCBA".getBytes("utf-8"));
    	final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    	for (int j = 0, k = 16; j < 8;) {
    		keyBytes[k++] = keyBytes[j++];
    	}

    	final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
    	final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    	final Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    	decipher.init(Cipher.DECRYPT_MODE, key);

    	// final byte[] encData = new
    	// sun.misc.BASE64Decoder().decodeBuffer(message);
    	final byte[] plainText = decipher.doFinal(message);

    	return new String(plainText, "UTF-8");
    }
}

Não tenho ideia onde está o erro… ainda mais porque nem os dois códigos java estão batendo.

Alguém tem alguma ideia de onde estou errando… Obrigado

Como eu havia dito, o seu problema é a derivação da chave a partir da senha, não o algoritmo “em si”.

http://www.example-code.com/java/crypt2_pbkdf1.asp

Pegue o seu codigo Java original e seu código C# original, e tente fazer as adaptações necessárias de acordo com o link acima.

EDIT - não vi que ele usa uma biblioteca de terceiros. De qualquer forma, procure por “PBKDF1 Java” no Google.

Opa valew entanglement, agora sim funcionou, acabamos adaptando o código C# com o código em java com BouncyCastle…

Agora estive olhando os dois códigos em java ( o com BouncyCastle e o com API padrão), não to conseguindo ver qual a diferença, ta meio confuso, um usa o md5 e o outro não.

Teria uma ideia de como ficaria o código com a API padrão??

Ha… jájá coloco o código em c# alterado. Obrigado.

Olha ai consegui, fiz umas alterações e pronto agora as duas classes java estão fazendo a mesma coisa. não sei se é a melhor forma mais funcionou rsrs, a falta de experiencia faz a gente quebrar bastante a cabeça.

Obrigadão pessoal.

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;

public class TripleDESTest {

    public static void main(String[] args) throws Exception {

    	String text = "teste";
    	final byte[] keyBytes = "12345678ABCDEFGHHGFEDCBA".getBytes();

    	byte[] codedtext = new TripleDESTest().encrypt(text, keyBytes);
    	String decodedtext = new TripleDESTest().decrypt(codedtext, keyBytes);

    	System.out.println(new BASE64Encoder().encode(codedtext)); // this is a byte array, you'll just see a reference to an array
    	System.out.println(decodedtext); // This correctly shows "kyle boon"
    }

    public byte[] encrypt(String message, byte[] chave) throws Exception {
    	//final MessageDigest md = MessageDigest.getInstance("md5"); //MD5, MD2, SHA, SHA-1, SHA-256, SHA-384 e SHA-512
    	//final byte[] digestOfPassword = md.digest("2012UNIMED24BOTUCATU0941".getBytes("utf-8"));
    	//final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    	/*for (int j = 0, k = 16; j < 8;) {
    		keyBytes[k++] = keyBytes[j++];
    	}*/
    	
    	
    	final SecretKey key = new SecretKeySpec(chave, "DESede");
    	//final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    	final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    	                                          
    	cipher.init(Cipher.ENCRYPT_MODE, key);

    	final byte[] plainTextBytes = message.getBytes("utf-8");
    	final byte[] cipherText = cipher.doFinal(plainTextBytes);
    	// final String encodedCipherText = new sun.misc.BASE64Encoder()
    	// .encode(cipherText);

    	return cipherText;
    }

    public String decrypt(byte[] message, byte[] chave) throws Exception {
    	//final MessageDigest md = MessageDigest.getInstance("md5");
    	/*final byte[] digestOfPassword = md.digest("2012UNIMED24BOTUCATU0941".getBytes("utf-8"));
    	final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    	for (int j = 0, k = 16; j < 8;) {
    		keyBytes[k++] = keyBytes[j++];
    	}*/
    	
    	final SecretKey key = new SecretKeySpec(chave, "DESede");
    	//final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    	final Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    	decipher.init(Cipher.DECRYPT_MODE, key);

    	// final byte[] encData = new
    	// sun.misc.BASE64Decoder().decodeBuffer(message);
    	final byte[] plainText = decipher.doFinal(message);

    	return new String(plainText, "UTF-8");
    }
}