Rijndael encrypt/decrypt выводит неправильно

Моя структура для шифрования/дешифрования С# выглядит следующим образом:

  • Шифр: Rijndael (AES)
  • Размер блока: 128 бит (16 байт).
  • Режим: CBC (цепочка блоков шифрования)
  • Ключ: хеш-фраза MD5.
  • IV: то же, что и ключ.
  • Кодировка данных: символ Base64
  • Кодировка UTF-8

Я использую вход Player для обоих входов в качестве теста, однако он не возвращает правильный хеш-выход MD5, а также есть небольшая проблема с моей функцией Decrypt для byte[] toEncryptArray = Convert.FromBase64String (toDecrypt);.

Неправильный вывод хэша и ошибка

playerID: Зашифрованный плеер: ZCKgr4veKtCDrD6mL+P6Yg==
FormatException: Неверная длина. System.Convert.FromBase64String (System.String s) (в /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Convert.cs:146) APIConnector.Decrypt (System.String toDecrypt) (в Assets /APIConnector.cs:122)

Любые идеи о том, что я могу сделать, чтобы 1) исправить эту ошибку и 2) получить правильный вывод хэша на основе приведенной выше структуры ym? Спасибо!

void submit(){

        Debug.Log ("playerID is: " + firstName + " encrypted is: " + Encrypt(firstName));
        Debug.Log ("password is: " + password + " decrypted is: " + Decrypt(password));

    }


    public static string Encrypt (string toEncrypt)
    {
        byte[] keyArray  = UTF8Encoding.UTF8.GetBytes ("SecretPassphrase");

        // 256-AES key
        byte[] toEncryptArray   = UTF8Encoding.UTF8.GetBytes (toEncrypt);

        RijndaelManaged rDel  = new RijndaelManaged ();
        rDel.Key              = keyArray;
        rDel.IV              = keyArray;
        rDel.Mode             = CipherMode.CBC;
        rDel.BlockSize        = 128;

        // http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx
        rDel.Padding   = PaddingMode.PKCS7;

        // better lang support
        ICryptoTransform cTransform  = rDel.CreateEncryptor ();

        byte[] resultArray   = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);

        return Convert.ToBase64String (resultArray, 0, resultArray.Length);
    }

    // 
    public static string Decrypt (string toDecrypt)
    {
        byte[] keyArray  = UTF8Encoding.UTF8.GetBytes ("SecretPassphrase");

        // AES-256 key
        byte[] toEncryptArray   = Convert.FromBase64String (toDecrypt);

        RijndaelManaged rDel  = new RijndaelManaged ();
        rDel.Key              = keyArray;
        rDel.IV              = keyArray;
        rDel.Mode             = CipherMode.CBC;
        rDel.BlockSize        = 128;

        // http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx
        rDel.Padding    = PaddingMode.PKCS7;

        // better lang support
        ICryptoTransform cTransform  = rDel.CreateDecryptor ();

        byte[] resultArray   = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);

        return UTF8Encoding.UTF8.GetString (resultArray);
    }

person DT.DTDG    schedule 26.05.2014    source источник
comment
Вы понимаете, что пытаетесь декодировать строку Player?   -  person Sergey Krusch    schedule 26.05.2014
comment
Извините, пришлось расшифровать строку пароля, обновить...   -  person DT.DTDG    schedule 26.05.2014


Ответы (2)


Вы должны передать зашифрованное значение в Decrypt, а не имя. Преобразование Base64 завершилось неудачно, поскольку имя не указано.

    Debug.Log ("playerID is: " + firstName + " encrypted is: " + Encrypt(firstName));
    Debug.Log ("password is: " + password + " decrypted is: " + Decrypt(firstName));

Должен быть

string enc = Encrypt(firstName);
Debug.Log ("playerID is: " + firstName + " encrypted is: " + enc);
Debug.Log ("password is: " + password + " decrypted is: " + Decrypt(enc));
person Oleg Gryb    schedule 26.05.2014
comment
круто, решает одну проблему, спасибо :) Просто хэш md5 неверен, и я не понимаю, почему.. Я использую все в соответствии со своей структурой или нет? - person DT.DTDG; 26.05.2014
comment
Использование MD5 в этом случае — ужасная идея с точки зрения безопасности, поскольку она подвержена коллизиям. Вам нужно использовать алгоритм растяжения ключа, чтобы надежно получить криптографический ключ из фразы-пароля. Другое название PBE или шифрование на основе пароля. Просто погуглите. - person Oleg Gryb; 26.05.2014
comment
В частности, вам нужно будет использовать Rfc2898DeriveBytes, который является .NET-реализацией PBKDF2. Проверьте эту ссылку: stackoverflow.com /вопросы/5392404/ - person Oleg Gryb; 26.05.2014
comment
Спасибо сейчас проверю :) - person DT.DTDG; 26.05.2014
comment
Пока вы это делаете, пожалуйста, используйте случайную соль для открытого текста. Если вы когда-нибудь повторите соль для шифрования определенного открытого текста (со временем), по крайней мере, также используйте случайный IV. - person Maarten Bodewes; 26.05.2014

Ваш метод submit не расшифровывает вашу зашифрованную строку, он пытается расшифровать вашу незашифрованную исходную строку. Изменение вашего метода submit на приведенный ниже приводит к тому, что программа выполняется без ошибок;

static void submit(){
    string password = Encrypt(firstName);
    Console.WriteLine ("playerID is: " + firstName + 
                       " encrypted is: " + password);
    Console.WriteLine ("password is: " + password + 
                       " decrypted is: " + Decrypt(password));
}

Кроме того, поскольку вы на самом деле не используете MD5 для своего ключа, вам повезло, что «SecretPassphrase» на самом деле составляет 16 символов, что является точной длиной ключа, который мог бы создать MD5. Изменение на более короткую или более длинную строку нарушит работу программы.

person Joachim Isaksson    schedule 26.05.2014
comment
Спасибо! Это решает одну проблему, теперь другая проблема заключается в том, что хэш (зашифрованный журнал) неверен. Видите ли вы что-нибудь еще, что могло бы сделать что-то, чтобы изменить его по сравнению с тем, чем он должен быть? - person DT.DTDG; 26.05.2014
comment
Кроме того, SecretPassphrase не является моим фактическим ключом, я просто использую его в моем примере, поскольку он 16-битный :), и мой ключ также 16-битный, не волнуйтесь :) - person DT.DTDG; 26.05.2014
comment
Что-нибудь сделать с тем, что я должен использовать MD5? - person DT.DTDG; 26.05.2014
comment
@DT.DTDG Если вы не используете MD5 в своем ключе, вы не получите того же результата, что и вы. Другими словами, если у вас есть что-то, с чем вам нужно быть совместимым, вам нужно будет ввести ключ MD5 так же, как это делает другая сторона. В противном случае (как указано в другом ответе) есть лучший выбор для растяжения клавиш в современных системах. - person Joachim Isaksson; 26.05.2014