3

I have to encrypt/decrypt data from a .Net based web service that is using the following code (based on Rijndael algorithm):

/**
 * Cifra una cadena texto con el algoritmo de Rijndael
 *
 * @param   plainMessage    mensaje plano (sin cifrar)
 * @param   p_strSpecialKey key especial
 * @return  string          texto cifrado en hexadecimal
 */
public static string AES_encryptString(String plainMessage, string p_strSpecialKey) {
  string strTxtEncrypt = "";

  // Crear una instancia del algoritmo de Rijndael
  try {
    Rijndael RijndaelAlg = Rijndael.Create();
    RijndaelAlg.KeySize = 128;
    RijndaelAlg.Mode = CipherMode.ECB;
    RijndaelAlg.Padding = PaddingMode.Zeros;

    byte[] Key = Encoding.UTF8.GetBytes(p_strSpecialKey);
    byte[] IV = RijndaelAlg.IV;

    int keySize = 32;
    Array.Resize(ref Key, keySize);

    // Establecer un flujo en memoria para el cifrado
    MemoryStream memoryStream = new MemoryStream();

    // Crear un flujo de cifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(memoryStream,
    RijndaelAlg.CreateEncryptor(Key, IV),
    CryptoStreamMode.Write);

    // Obtener la representación en bytes de la información a cifrar
    byte[] plainMessageBytes = Encoding.UTF8.GetBytes(plainMessage);

    // Cifrar los datos enviándolos al flujo de cifrado
    cryptoStream.Write(plainMessageBytes, 0, plainMessageBytes.Length);
    cryptoStream.FlushFinalBlock();

    // Obtener los datos datos cifrados como un arreglo de bytes
    byte[] cipherMessageBytes = memoryStream.ToArray();

    // Cerrar los flujos utilizados
    memoryStream.Close();
    cryptoStream.Close();

    strTxtEncrypt = ByteToHex(cipherMessageBytes);
  } catch (Exception ex) {
    AddToFile("Error al encriptar el valor: " + plainMessage + " con la clave especial: " + p_strSpecialKey + " " + ex.ToString());
  }

  return strTxtEncrypt;
}

/**
 * Descifra una cadena texto con el algoritmo de Rijndael
 *
 * @param   encryptedMessage    mensaje cifrado en hexadecimal
 * @param   p_strSpecialKey key especial
 * @return  string              texto descifrado (plano)
 */
public static string AES_decryptString(String encryptedMessage, string p_strSpecialKey) {
  string strDecrypt = "";

  // Crear una instancia del algoritmo de Rijndael
  try {
    Rijndael RijndaelAlg = Rijndael.Create();
    RijndaelAlg.KeySize = 128;
    RijndaelAlg.Mode = CipherMode.ECB;
    RijndaelAlg.Padding = PaddingMode.Zeros;

    byte[] Key = Encoding.UTF8.GetBytes(p_strSpecialKey);
    byte[] IV = RijndaelAlg.IV;

    int keySize = 32;
    Array.Resize(ref Key, keySize);

    // Obtener la representación en bytes del texto cifrado
    byte[] cipherTextBytes = HexToByteArray(encryptedMessage);

    // Crear un arreglo de bytes para almacenar los datos descifrados
    byte[] plainTextBytes = new byte[cipherTextBytes.Length];

    // Crear un flujo en memoria con la representación de bytes de la información cifrada
    MemoryStream memoryStream = new MemoryStream(cipherTextBytes);

    // Crear un flujo de descifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(memoryStream,
    RijndaelAlg.CreateDecryptor(Key, IV),
    CryptoStreamMode.Read);

    // Obtener los datos descifrados obteniéndolos del flujo de descifrado
    int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

    // Cerrar los flujos utilizados
    memoryStream.Close();
    cryptoStream.Close();

    // Retornar la representación de texto de los datos descifrados
    strDecrypt = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).Replace("\0", "");
  } catch (Exception ex) {
    AddToFile("Error al desencriptar el valor: " + encryptedMessage + " con la clave especial: " + p_strSpecialKey + " " + ex.ToString());
  }

  return strDecrypt;
}

I have investigated the way to do the same on Ruby and I found this answer (How to decode Rijndael in ruby (encoded in VB.net)) but it doesn't works for me. Also, I'm not sure of what value i have to use for the iv. The web service brings me a Token that i have to use as the key (100% sure about that), but, actually don't know what i'm missing up.

The code I'm using for encrypt is:

# /lib/crypt.rb
module Crypt
  ...
  def Crypt.encrypt(data, key, iv, cipher_type)
    aes = OpenSSL::Cipher::Cipher.new(cipher_type)
    aes.encrypt
    aes.key = key
    aes.iv = iv
    aes.update(data) + aes.final
  end
end

# ../ws.rb
...
token = "8c5d0e6b93cf5d38d7a076b2db35ee6d" #this is a one of the tokens i received
iv = token
Crypt.encrypt(a_serialized_json,token,iv,"AES-128-CBC")

The encrypted serialized json data that I have to send must be like a hexdigest string like this "f0997ddbb17b08913e00b6fb2541312c1cfdda85e555451a1832df076a5d4a5f7d81d8db92715eade144e9696dfbe9eea573baa8ea90cdbe5baadf32fdeb6db8c9ab6743f8eeeb508921999d7513fad3". But the method described on the link generates a encrypted string like this ""^w\x9A\x90B\xDC\f\x16\xB8\xBDt\xFBo\xD7r\x97"".

Any idea of what I'm doing wrong or what I'm missing?

UPDATE: I figured out that the string output I'm getting is a byte array, and i have to convert this byte array to an hex string. I'm using the following aproach (https://github.com/atomicobject/hex_string/blob/master/lib/hex_string.rb). But, still not sure if Cypher is properly configured to acts as the C# code.

Community
  • 1
  • 1

1 Answers1

0

Finally, I found a library that exactly match the C# code and is ruby-mcrypt (https://github.com/kingpong/ruby-mcrypt). And the encryption/decryption code i used is this:

require 'mcrypt'

module Crypt
  def Crypt.m_encrypt(data, key)
    crypto = Mcrypt.new(:rijndael_128, :ecb, key, nil, :zeros)
    encrypted_data = crypto.encrypt(data)
    encrypted_data
  end

  def Crypt.m_decrypt(data, key)
    crypto = Mcrypt.new(:rijndael_128, :ecb, key, nil, :zeros)
    crypto.decrypt(data)
  end
end

IMPORTANT: This C# Rjandael library doesn't uses the IV, for that reason i'm giving nil parameter as IV to Mcrypt.

This is only the encryption/decryption section, i'm also converting string to hexa format. Hope it can help somebody else!

  • Hi, I tried to compare the C# and your ruby and my encrypt decrypt come up with totally different answers. Is there more to your ruby code that you didn't post? – Joelio Aug 02 '17 at 01:15
  • I don't remember the exact input/output provided both the ruby and the C# code, and unfortunately i lost the source code. The only thing that it's not specified it's that the provided keys must be the same of course. Maybe future version of the gem changes output string a little from that time – Cristian Carreño Aug 03 '17 at 02:06