2015-06-03 2 views
3

я должен зашифровать/расшифровать данные, основанного на .Net веб-сервиса, который, используя следующий код (на основе Rijndael алгоритм):Перенастройка C# .Net зашифровать/расшифровать алгоритм Руби

/** 
* 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 исследовали способ сделать то же самое на Ruby, и я нашел этот ответ (How to decode Rijndael in ruby (encoded in VB.net)), но это не работает для меня. Кроме того, я не уверен, какое значение я должен использовать для iv. Веб-сервис приносит мне токен, который я должен использовать в качестве ключа (100% уверен в этом), но на самом деле не знаю, чего я пропустил.

код я использую для шифрования является:

# /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") 

зашифрованный сериализованная JSON данные, которые я должен послать должен быть как hexdigest строки, как этот «f0997ddbb17b08913e00b6fb2541312c1cfdda85e555451a1832df076a5d4a5f7d81d8db92715eade144e9696dfbe9eea573baa8ea90cdbe5baadf32fdeb6db8c9ab6743f8eeeb508921999d7513fad3». Но метод, описанный в ссылке, генерирует зашифрованную строку, подобную этой ""^w \ x9A \ x90B \ xDC \ f \ x16 \ xB8 \ xBDt \ xFBo \ xD7r \ x97 "".

Любая идея о том, что я делаю неправильно или что мне не хватает?

UPDATE: Я понял, что вывод строки, который я получаю, представляет собой массив байтов, и мне нужно преобразовать этот массив байтов в шестнадцатеричную строку. Я использую следующий aproach (https://github.com/atomicobject/hex_string/blob/master/lib/hex_string.rb). Но, все еще не уверен, что Cypher правильно настроен, чтобы действовать как код C#.

ответ

0

Наконец-то я нашел библиотеку, которая точно соответствует C# -коду и ruby-mcrypt (https://github.com/kingpong/ruby-mcrypt). И код шифрования/дешифрования я использовал это:

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 

ВАЖНО: Эта библиотека C# Rjandael не использует IV, по этой причине я даю параметр ноль в IV в Mcrypt.

Это только раздел шифрования/дешифрования, я также преобразовываю строку в формат hexa. Надеюсь, это может помочь кому-то еще!

+0

Привет, я попытался сравнить C# и ваш ruby, а мой расшифрованный шифр придумал совершенно разные ответы. Есть ли еще ваш код ruby, который вы не опубликовали? – Joelio

+0

Я не помню точный ввод/вывод, предоставляемый как рубином, так и кодом C#, и, к сожалению, я потерял исходный код. Единственное, что не указано, что предоставленные ключи должны быть одинаковыми, конечно. Возможно, будущая версия драгоценного камня немного изменит выходную строку с того времени –