Пример кода PHP / C# AES-шифрование - случайное IV - PullRequest
0 голосов
/ 22 марта 2020

Я нашел реализацию шифрования / дешифрования AES, которая должна работать в PHP и C#: https://odan.github.io/2017/08/10/aes-256-encryption-and-decryption-in-php-and-csharp.html

Однако в этом примере IV всегда 0, что не хорошо. Итак, как предлагает автор, я использую функцию openssl_random_pseudo_bytes ():

  $ivlen = openssl_cipher_iv_length($method);
  $iv = openssl_random_pseudo_bytes($ivlen);

Однако сейчас проблема в том, что мне нужно где-то хранить IV, чтобы приложение C# могло использовать его для дешифрования. Моя идея состояла в том, чтобы base64_encode это и добавить его к зашифрованному сообщению с ":", разделяя оба, так, чтобы я мог просто разделить строку, затем base64 декодировать это в C# и может использовать IV. Однако это не работает. Это код:

public string DecryptString(string cipherText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;

    // Set key and IV
    byte[] aesKey = new byte[32];
    Array.Copy(key, 0, aesKey, 0, 32);
    encryptor.Key = aesKey;
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

    // Will contain decrypted plaintext
    string plainText = String.Empty;

    try {
        // Convert the ciphertext string into a byte array
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Decrypt the input ciphertext string
        cryptoStream.Write(cipherBytes, 0, cipherBytes . Length);

        // Complete the decryption process
        cryptoStream.FlushFinalBlock();

        // Convert the decrypted data from a MemoryStream to a byte array
        byte[] plainBytes = memoryStream.ToArray();

        // Convert the decrypted byte array to string
        plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
    } finally {
        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();
    }

    // Return the decrypted data as a string
    return plainText;
}

И вот как я пытаюсь вызвать функцию с IV, добавленным к зашифрованному сообщению:

private void btnDecrypt_Click(object sender, EventArgs e)
        {
            string encrypted = txtEncrypted.Text;
            string password = txtPW.Text;
            string[] temp = encrypted.Split(":".ToCharArray());
            string iv_str = temp[0];
            encrypted = temp[1];
            SHA256 mySHA256 = SHA256Managed.Create();
            byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));
            iv_str = Encoding.Default.GetString(Convert.FromBase64String(iv_str));
            byte[] iv = Encoding.ASCII.GetBytes(iv_str);

            txtDecrypted.Text = this.DecryptString(encrypted, key, iv); 
        }

Не работает. Он что-то расшифровывает, но это просто gibberi sh, а не сообщение, которое я зашифровал в PHP. Я думаю, что это как-то связано с IV.

1 Ответ

0 голосов
/ 24 марта 2020

@ Топако: Большое спасибо ... теперь я понимаю, в чем была моя ошибка. Это работает теперь с сгенерированным IV. Кстати, еще два вопроса о силе шифрования:

  1. Можно ли использовать следующую функцию для генерации IV (GenerateIV () по некоторым причинам не будет работать) :

    байт [] iv = новый байт [16]; Random rnd = new Random (); rnd.NextBytes (iv);

  2. Я добавил случайно сгенерированную соль в пароль пользователя, чтобы ключ представлял собой га sh из пароля пользователя и соли. Я также добавляю соль вместе с теперь случайно сгенерированным IV к сообщению. Затем для процесса расшифровки я использую предварительно добавленную соль и ключ, который вводит пользователь. Работает до сих пор. Но ослабляет ли это шифрование? Нет, верно?

Большое спасибо.

// Редактировать: Формат кода не работает, не знаю почему.

...