Не удается открыть XML после расшифровки 1 байт для многих? - PullRequest
2 голосов
/ 17 ноября 2011

Я пытаюсь зашифровать XML, и после расшифровки я получаю слишком много байтов - вероятно, из-за заполнения. Это мой код Как я могу изменить это, чтобы заставить это работать?

public byte[] encryptData(byte[] source,string key)
{
    byte[] btKeyInBytes = UTF8Encoding.UTF8.GetBytes(key);
    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(key, btKeyInBytes);

    AesManaged encryptor = new AesManaged();
    encryptor.Padding = PaddingMode.Zeros;

    using (MemoryStream encryptStream = new MemoryStream())
    {
        using (CryptoStream encStream = new CryptoStream(encryptStream, encryptor.CreateEncryptor(rfc.GetBytes(16), rfc.GetBytes(16)), CryptoStreamMode.Read))
        {
            //Read from the input stream, then encrypt and write to the output stream.
            encStream.Write(source, 0, source.Length);
            encStream.FlushFinalBlock();
            encryptor.Clear();
        }
        encryptStream.Flush();
        encryptedSource = encryptStream.ToArray();
    }
    return encryptedSource;
}

public byte[] decryptData(byte[] source, string key)
{
    byte[] encryptedSource = null;

    byte[] btKeyInBytes = UTF8Encoding.UTF8.GetBytes(key);
    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(key, btKeyInBytes);

    AesManaged encryptor = new AesManaged();
    encryptor.Padding = PaddingMode.Zeros;

    using (MemoryStream encryptStream = new MemoryStream())
    {
        using (CryptoStream encStream = new CryptoStream(encryptStream, encryptor.CreateDecryptor(rfc.GetBytes(16), rfc.GetBytes(16)), CryptoStreamMode.Write))
        {
            //Read from the input stream, then encrypt and write to the output stream.
            encStream.Write(source, 0, source.Length);
            encStream.FlushFinalBlock();
            encryptor.Clear();
        }
        encryptStream.Flush();
        encryptedSource = encryptStream.ToArray();
    }

    return encryptedSource;
}

Кажется, что заполнение дает мне 1 дополнительный байт во время расшифровки

Ответы [ 2 ]

1 голос
/ 18 ноября 2011

Я понял!

Теперь давайте попробуем объяснить.

Допустим, у меня есть файл размером 927 байт.

Что я делаю, так это читаю этот файл и делю его на части по 656 байт. Этот байтовый массив из 656 байтов шифруется. Второй массив будет 271 байт.

В каждом блоке для шифрования я использовал заполнение. При расшифровке вы не сможете узнать, в каком блоке было заполнение, потому что теперь каждый блок можно разделить на 16 (из-за заполнения в шифровании). По сути, я хочу использовать только отступы для последнего блока (271).

так что это мой новый код:

public byte[] encryptData(byte[] source, string key, bool padding)
{
    byte[] encryptedSource = null;


    byte[] btKeyInBytes = UTF8Encoding.UTF8.GetBytes(key);
    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(key, btKeyInBytes);

    AesManaged encryptor = new AesManaged();
    //encryptor.Mode = CipherMode.CFB; 
    encryptor.KeySize = 128;          // in bits     
    encryptor.Key = new byte[128 / 8];  // 16 bytes for 128 bit encryption     
    encryptor.IV = new byte[128 / 8];
    if (padding) { encryptor.Padding = PaddingMode.PKCS7; }
    else { encryptor.Padding = PaddingMode.None; }


    using (MemoryStream encryptStream = new MemoryStream())
    {
        using (CryptoStream encStream =
                   new CryptoStream(encryptStream,
                                    encryptor.CreateEncryptor(rfc.GetBytes(16),
                                                              rfc.GetBytes(16)),
                                    CryptoStreamMode.Write))
        {
            //Read from the input stream, then encrypt and write to the output stream.
            encStream.Write(source, 0, source.Length);
        }
        encryptStream.Flush();
        encryptedSource = encryptStream.ToArray();
    }
    return encryptedSource;
}

public byte[] decryptData(byte[] source, string key,bool padding)
{
    byte[] encryptedSource = null;

    byte[] btKeyInBytes = UTF8Encoding.UTF8.GetBytes(key);
    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(key, btKeyInBytes);

    AesManaged encryptor = new AesManaged();
    encryptor.Key = new byte[128 / 8];  // 16 bytes for 128 bit encryption     
    encryptor.IV = new byte[128 / 8];
    if (padding) { encryptor.Padding = PaddingMode.PKCS7; }
    else { encryptor.Padding = PaddingMode.None; }


    using (MemoryStream encryptStream = new MemoryStream())
    {
        using (CryptoStream encStream =
                 new CryptoStream(encryptStream,
                                  encryptor.CreateDecryptor(rfc.GetBytes(16),
                                                            rfc.GetBytes(16)),
                                  CryptoStreamMode.Write))
        {
            //Read from the input stream, then encrypt and write to the output stream.
            encStream.Write(source, 0, source.Length);
        }
        encryptStream.Flush();
        encryptedSource = encryptStream.ToArray();

    }

    return encryptedSource;
}

Надеюсь, это поможет!

1 голос
/ 17 ноября 2011

Если у вас проблема с заполнением, то PaddingMode.Zeros - наихудший выбор, поскольку нули не всегда могут быть надежно удалены.Лучше использовать заполнение PKCS7.

Также возможно, что кодирование конца строки изменилось между системами.Некоторые системы используют один байт, в то время как другие системы используют два байта.Вам действительно нужно посмотреть, что именно находится в расшифрованном файле, побайтно, как предлагает @Rup.

...