Bad PKCS7 Ошибка заполнения: неверная длина 106

1

Я пытаюсь зашифровать и дешифровать с помощью следующих функций, однако это приводит к плохой ошибке заполнения.

Если я устанавливаю PaddingMode в None он возвращает некоторые альфа-символы и случайные символы в Log.

Возможно, я что-то упустил из настройки правильной структуры, которая выглядит следующим образом:

  • Cipher Rijndael (AES)
  • Размер блока 128 бит (16 байт)
  • Ключ режима CBC (Cipher Block Chaining)
  • MD5 хэш-кодовая фраза
  • IV То же, что и ключ
  • Кодирование данных Base64 Character
  • Кодировка UTF-8

Любая помощь, связанная с исправлением этой ошибки и любая помощь в обеспечении вышеуказанной структуры, будет с благодарностью! благодаря

ошибка

CryptographicException: Bad PKCS7 padding. Invalid length 106.
Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (PaddingMode padding, Int32 length, Int32 position) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs:363)
Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs:515)
Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs:554)
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Security.Cryptography/RijndaelManagedTransform.cs:94)
APIConnector.Decrypt (System.String toDecrypt) (at Assets/APIConnector.cs:85)

Мой код

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using System.IO;

public class APIConnector : MonoBehaviour {

    // Use this for initialization
    void Start () {

        Debug.Log ("Starting API connector");


    }

    // Update is called once per frame
    void Update () {



    }

    static string data;
    string firstName="";
    string password="";

    void OnGUI() {

        firstName = GUILayout.TextField (firstName, GUILayout.Width(300));
        password = GUILayout.TextField (password, GUILayout.Width(300));

        if (GUILayout.Button ("Submit"))
                        submit ();

    }

    //Our functions

    void submit(){

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

    }


            public static string Encrypt (string toEncrypt)
            {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes ("SecretPassphrase");
                // 256-AES key
        int numBytes = System.Text.Encoding.UTF8.GetBytes(toEncrypt).Length;
        Debug.Log ("Bytes: " + numBytes);
                byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toEncrypt);
                RijndaelManaged rDel = new RijndaelManaged ();
                rDel.Key = keyArray;
                rDel.BlockSize = 128;
                rDel.Mode = CipherMode.CBC;
                // 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[] encryptedData = System.Convert.FromBase64String(toDecrypt);
                //byte[] toEncryptArray = Convert.FromBase64String (toDecrypt);
                RijndaelManaged rDel = new RijndaelManaged ();
                rDel.Key = keyArray;
                rDel.BlockSize = 128;
                rDel.Mode = CipherMode.CBC;
                rDel.IV = rDel.Key;
                // 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 (encryptedData, 0, encryptedData.Length);
                return UTF8Encoding.UTF8.GetString (resultArray);
            }


}
Теги:
base64
cryptography
rijndael
rijndaelmanaged

1 ответ

3
Лучший ответ

Кажется, вы не устанавливаете IV при шифровании, и поэтому случайный IV будет использоваться автоматически. Поскольку вы устанавливаете IV при расшифровке (и это будет не то же самое, что использовалось при шифровании), первый выходной блок будет поврежден. Если сообщение достаточно короткое (<1 блок), то добавление также будет искажено, что приведет к этой ошибке.

Как обычно, я отмечу, что среди других возможных проблем использование одного и того же ключа IV - это плохая практика, а также использование Encoding.UTF8.GetBytes() для деривации ключей.

  • 0
    Спасибо за ваш ответ. Я довольно новичок в C # и даже новее в C # шифровании. Можете ли вы отредактировать свой ответ, чтобы привести пример исправления? Спасибо!
  • 0
    @ DT.DTDG - Вам просто нужно добавить строку: rDel.IV = rDel.Key; на ваш метод Encrypt , в том же месте, что и в вашем методе Decrypt .
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню