Criptografia AES - Java e C#

Galera, preciso de uma ajuda urgente:

Eu tenho um webservice em Java que devolve algumas informações criptografadas, agora tenho que ler essas informações em um componente C#, porém não consigo fazer o decrypt, se alguém manja de C# e puder me ajudar, agradeço muito, segue minha classe de criptografia.

a chave é gerada em 128 e depois convertida para String Hexa. No Java e clientes java funciona na boa, só não estou conseguindo fazer a equivalência de função no C#

package br.com.tratomais.bancaseguros.utils;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

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

import br.com.tratomais.bancaseguros.exception.DALayerException;

public class Seguranca {
	
	private static final String hexDigits = "0123456789abcdef";
	
	/**
	 * Construtor
	 */
	public Seguranca() {
	}
	
	/**
	* Realiza a encriptação apartir de uma chave.
	* @param Key - chave de codificação.
	* @param message - menssagem a ser codificada.
	* @return String - O resultado da criptografia em hexadecimal.
	* @throws Exception - Caso o algoritmo fornecido não seja válido
	*/
	public static String encrypt(String key, String message) throws Exception {

		byte[] hexByte = asByte(key);
		SecretKeySpec skeySpec = new SecretKeySpec(hexByte, "AES");

		// Instantiate the cipher
		Cipher cipher = Cipher.getInstance("AES");

		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

		byte[] encrypted = cipher.doFinal((message.getBytes()));
		return asHex(encrypted);
	}

	/**
	* Realiza a dencriptação apartir de uma chave.
	* @param Key - chave de codificação.
	* @param message - menssagem a ser decodificada.
	* @return String - Retorna a String original.
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	* @throws Exception - Caso o algoritmo fornecido não seja válido
	*/	
	public static String decrypt(String key, String hex) throws DALayerException{

		byte[] hexByte = asByte(key);
		SecretKeySpec skeySpec = new SecretKeySpec(hexByte, "AES");

		Cipher cipher = null;
		try {
			cipher = Cipher.getInstance("AES");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}

		byte[] encrypted = new BigInteger(hex, 16).toByteArray();

		try {
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}
		
		byte[] original = null;
		
		try {
			original = cipher.doFinal(encrypted);
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}

		String originalString = new String(original);

		return originalString;
	}

	private static String generateKey() throws NoSuchAlgorithmException {
		// Get the KeyGenerator
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128); // 192 and 256 bits may not be available

		// Generate the secret key specs.
		SecretKey skey = kgen.generateKey();
		byte[] raw = skey.getEncoded();

		return asHex(raw);
	}
	
	/**
	* Realiza um digest em um array de bytes através do algoritmo especificado
	* @param input - O array de bytes a ser criptografado
	* @param algoritmo - O algoritmo a ser utilizado
	* @return String - O resultado da criptografia
	* @throws NoSuchAlgorithmException - Caso o algoritmo fornecido não seja
	* válido
	*/
	public static String digest(byte[] input, String algoritmo)	throws DALayerException {
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance(algoritmo);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		md.reset();
		
		return asHex(md.digest(input));
	}	
	
	/**
	 * Converte o array de bytes em uma representação hexadecimal.
	 * 
	 * @param input - O array de bytes a ser convertido.
	 * @return Uma String com a representação hexa do array
	 */
	public static String asHex(byte[] b) {
		StringBuffer buf = new StringBuffer();

		for (int i = 0; i < b.length; i++) {
			int j = (b[i]) & 0xFF;
			buf.append(hexDigits.charAt(j / 16));
			buf.append(hexDigits.charAt(j % 16));
		}

		return buf.toString();
	}

	/**
	 * Converte uma String hexa no array de bytes correspondente.
	 * 
	 * @param hexa
	 *            - A String hexa
	 * @return O vetor de bytes
	 * @throws IllegalArgumentException
	 *             - Caso a String não sej auma representação haxadecimal válida
	 */
	public static byte[] asByte(String hexa) throws IllegalArgumentException {

		// verifica se a String possui uma quantidade par de elementos
		if (hexa.length() % 2 != 0) {
			throw new IllegalArgumentException("String hexa inválida");
		}
		
		byte[] b = new byte[hexa.length() / 2];
		  
		for (int i = 0; i < hexa.length(); i += 2) {
			b[i / 2] = (byte) ((hexDigits.indexOf(hexa.charAt(i)) << 4) | (hexDigits.indexOf(hexa.charAt(i + 1))));
		}
		return b;
	}
}

Muito obrigado a todos.

abs

ahhhh! dei uma pesquisada nos componentes microsoft e encontrei algo semelhante ao Java http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx

porém não consegui fazer funcionar, não entendi muito bem o lance do vetor. na verdade acho que é algum problema em converter o hex em byte array no c#, pois retorna um erro assim: O preenchimento é inválido e não pode ser removido.

Segue a classe de teste em C#:

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                RijndaelManaged myRijndael = new RijndaelManaged();

                byte[] IV = Encoding.ASCII.GetBytes("128");

                string encrypted = "6143b50e03de7b3789693ff65b108565";

                Byte[] _Value2 = new Byte[encrypted.Length / 2];
                for (Int32 _Index = 0; _Index < _Value2.Length; _Index++)
                {
                    Byte.TryParse(encrypted.Substring(_Index * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out _Value2[_Index]);
                }
                
                string chave = "6143b50e03de7b3789693ff65b108565";

                Byte[] _Value = new Byte[chave.Length / 2];
                for(Int32 _Index = 0; _Index < _Value.Length; _Index++)
                {
                    Byte.TryParse(chave.Substring(_Index * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out _Value[_Index]);
                }

                // Decrypt the bytes to a string.
                string roundtrip = decryptStringFromBytes_AES(_Value, _Value2, myRijndael.IV);

                //Display the original data and the decrypted data.
                Console.WriteLine("Original:   {0}", encrypted);
                Console.WriteLine("Round Trip: {0}", roundtrip);

            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
        }

muito obrigado a todos.

abs

Pessoal, consegui resolver parcialmente o problema, consigo gerar o decrypt porém está saindo com alguns caracteres estranhos no final da palavra: “lock2dog\b\b\b\b\b\b\b\b” o resultado correto seria “lock2dog”.

segue o código:

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                MemoryStream msDecrypt = null;
                CryptoStream csDecrypt = null;
                StreamReader srDecrypt = null;

                RijndaelManaged aesAlg = null;

                string plaintext = null;

                string encrypted = "1df3e93a35a0b3561388f0f5db48cbfc";
                byte[] byteArray = asByte(encrypted);
                
                string chave = "6143b50e03de7b3789693ff65b108565";
                byte[] _Value2 = asByte(chave);

                aesAlg = new RijndaelManaged();
                aesAlg.Key = _Value2;
                aesAlg.Mode = CipherMode.ECB;
                aesAlg.Padding = PaddingMode.Zeros;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                msDecrypt = new MemoryStream(byteArray);
                csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
                srDecrypt = new StreamReader(csDecrypt);

                plaintext = srDecrypt.ReadToEnd();

                Console.WriteLine("Round Trip: {0}", plaintext);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
        }

valeu hein!!!

Troque PaddingMode.Zeros por PaddingMode.PKCS7

Ohhhhhh valeu mesmo…funcionou…

ABS